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