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 // When passing huge structs by value, SystemZ uses pointers, therefore this 12 // test in its present form is unfortunately not applicable. 13 // ABI says: "A struct or union of any other size <snip>. Replace such an 14 // argument by a pointer to the object, or to a copy where necessary to enforce 15 // call-by-value semantics." 16 // XFAIL: s390x 17 18 #include <sanitizer/msan_interface.h> 19 #include <assert.h> 20 21 // This test assumes that ParamTLS size is 800 bytes. 22 23 // This test passes poisoned values through function argument list. 24 // In case of overflow, argument is unpoisoned. 25 #define OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == -1) 26 // In case of no overflow, it is still poisoned. 27 #define NO_OVERFLOW(x) assert(__msan_test_shadow(&x, sizeof(x)) == 0) 28 29 #if defined(__x86_64__) 30 // In x86_64, if argument is partially outside tls, it is considered completely 31 // unpoisoned 32 #define PARTIAL_OVERFLOW(x) OVERFLOW(x) 33 #else 34 // In other archs, bigger arguments are splitted in multiple IR arguments, so 35 // they are considered poisoned till tls limit. Checking last byte of such arg: 36 #define PARTIAL_OVERFLOW(x) assert(__msan_test_shadow((char *)(&(x) + 1) - 1, 1) == -1) 37 #endif 38 39 40 template<int N> 41 struct S { 42 char x[N]; 43 }; 44 45 void f100(S<100> s) { 46 NO_OVERFLOW(s); 47 } 48 49 void f800(S<800> s) { 50 NO_OVERFLOW(s); 51 } 52 53 void f801(S<801> s) { 54 PARTIAL_OVERFLOW(s); 55 } 56 57 void f1000(S<1000> s) { 58 PARTIAL_OVERFLOW(s); 59 } 60 61 void f_many(int a, double b, S<800> s, int c, double d) { 62 NO_OVERFLOW(a); 63 NO_OVERFLOW(b); 64 PARTIAL_OVERFLOW(s); 65 OVERFLOW(c); 66 OVERFLOW(d); 67 } 68 69 // -8 bytes for "int a", aligned by 8 70 // -2 to make "int c" a partial fit 71 void f_many2(int a, S<800 - 8 - 2> s, int c, double d) { 72 NO_OVERFLOW(a); 73 NO_OVERFLOW(s); 74 PARTIAL_OVERFLOW(c); 75 OVERFLOW(d); 76 } 77 78 int main(void) { 79 S<100> s100; 80 S<800> s800; 81 S<801> s801; 82 S<1000> s1000; 83 f100(s100); 84 f800(s800); 85 f801(s801); 86 f1000(s1000); 87 88 int i; 89 double d; 90 f_many(i, d, s800, i, d); 91 92 S<800 - 8 - 2> s788; 93 f_many2(i, s788, i, d); 94 return 0; 95 } 96