xref: /llvm-project/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp (revision cd269daf25016f7115424a51ab5e7977a80e072d)
1 // RUN: %clangxx_asan -O0 %s -o %t
2 // RUN: not %run %t 0 2>&1 | FileCheck %s
3 // RUN: not %run %t 1 2>&1 | FileCheck %s
4 // RUN: not %run %t 2 2>&1 | FileCheck %s
5 // RUN: not %run %t 3 2>&1 | FileCheck %s
6 // RUN: not %run %t 4 2>&1 | FileCheck %s
7 // RUN: not %run %t 5 2>&1 | FileCheck %s
8 // RUN: not %run %t 6 2>&1 | FileCheck %s
9 // RUN: not %run %t 7 2>&1 | FileCheck %s
10 // RUN: not %run %t 8 2>&1 | FileCheck %s
11 // RUN: not %run %t 9 2>&1 | FileCheck %s
12 // RUN: not %run %t 10 2>&1 | FileCheck %s
13 
14 #include <stdlib.h>
15 #include <string>
16 #include <vector>
17 
18 template <class T> struct Ptr {
StorePtr19   void Store(T *ptr) { t = ptr; }
20 
AccessPtr21   void Access() { *t = {}; }
22 
23   T *t;
24 };
25 
26 template <class T, size_t N> struct Ptr<T[N]> {
27   using Type = T[N];
StorePtr28   void Store(Type *ptr) { t = *ptr; }
29 
AccessPtr30   void Access() { *t = {}; }
31 
32   T *t;
33 };
34 
test()35 template <class T> __attribute__((noinline)) void test() {
36   Ptr<T> ptr;
37   {
38     T x;
39     ptr.Store(&x);
40   }
41 
42   ptr.Access();
43   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
44   // CHECK:  #{{[0-9]+}} 0x{{.*}} in {{(void )?test.*\((void)?\) .*}}use-after-scope-types.cpp
45   // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame
46   // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x'
47 }
48 
main(int argc,char ** argv)49 int main(int argc, char **argv) {
50   using Tests = void (*)();
51   Tests tests[] = {
52     &test<bool>,
53     &test<char>,
54     &test<int>,
55     &test<double>,
56     &test<float>,
57     &test<void*>,
58     &test<std::vector<std::string>>,
59     &test<int[3]>,
60     &test<int[1000]>,
61     &test<char[3]>,
62     &test<char[1000]>,
63   };
64 
65   int n = atoi(argv[1]);
66   if (n == sizeof(tests) / sizeof(tests[0])) {
67     for (auto te : tests)
68       te();
69   } else {
70     tests[n]();
71   }
72 
73   return 0;
74 }
75