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 34template<int N> 35struct S { 36 char x[N]; 37}; 38 39void f100(S<100> s) { 40 NO_OVERFLOW(s); 41} 42 43void f800(S<800> s) { 44 NO_OVERFLOW(s); 45} 46 47void f801(S<801> s) { 48 PARTIAL_OVERFLOW(s); 49} 50 51void f1000(S<1000> s) { 52 PARTIAL_OVERFLOW(s); 53} 54 55void 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 65void 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 72int 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