1 // ParamTLS has limited size. Everything that does not fit is considered fully 2 // initialized. 3 4 // RUN: %clangxx_msan -O0 %s -o %t && %run %t 5 // RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t 6 // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t 7 // 8 // AArch64 fails with: 9 // void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed 10 // XFAIL: aarch64 11 12 #include <sanitizer/msan_interface.h> 13 #include <assert.h> 14 15 // This test assumes that ParamTLS size is 800 bytes. 16 17 // This test passes poisoned values through function argument list. 18 // In case of overflow, argument is unpoisoned. 19 #define OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == -1) 20 // In case of no overflow, it is still poisoned. 21 #define NO_OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == 0) 22 23 #if defined(__x86_64__) 24 // In x86_64, if argument is partially outside tls, it is considered completly 25 // unpoisoned 26 #define PARTIAL_OVERFLOW(x) OVERFLOW(x) 27 #else 28 // In other archs, bigger arguments are splitted in multiple IR arguments, so 29 // they are considered poisoned till tls limit. Checking last byte of such arg: 30 #define PARTIAL_OVERFLOW(x) assert(__msan_test_shadow((char *)(&(x) + 1) - 1, 1) == -1) 31 #endif 32 33 34 template<int N> 35 struct S { 36 char x[N]; 37 }; 38 39 void f100(S<100> s) { 40 NO_OVERFLOW(s); 41 } 42 43 void f800(S<800> s) { 44 NO_OVERFLOW(s); 45 } 46 47 void f801(S<801> s) { 48 PARTIAL_OVERFLOW(s); 49 } 50 51 void f1000(S<1000> s) { 52 PARTIAL_OVERFLOW(s); 53 } 54 55 void f_many(int a, double b, S<800> s, int c, double d) { 56 NO_OVERFLOW(a); 57 NO_OVERFLOW(b); 58 PARTIAL_OVERFLOW(s); 59 OVERFLOW(c); 60 OVERFLOW(d); 61 } 62 63 // -8 bytes for "int a", aligned by 8 64 // -2 to make "int c" a partial fit 65 void f_many2(int a, S<800 - 8 - 2> s, int c, double d) { 66 NO_OVERFLOW(a); 67 NO_OVERFLOW(s); 68 PARTIAL_OVERFLOW(c); 69 OVERFLOW(d); 70 } 71 72 int main(void) { 73 S<100> s100; 74 S<800> s800; 75 S<801> s801; 76 S<1000> s1000; 77 f100(s100); 78 f800(s800); 79 f801(s801); 80 f1000(s1000); 81 82 int i; 83 double d; 84 f_many(i, d, s800, i, d); 85 86 S<800 - 8 - 2> s788; 87 f_many2(i, s788, i, d); 88 return 0; 89 } 90