1 | // RUN: %clangxx_asan -O1 %s -o %t |
2 | // RUN: not %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK0 |
3 | // RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1 |
4 | // RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2 |
5 | // RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3 |
6 | |
7 | // MSVC doesn't support GCC style inline ASM |
8 | // UNSUPPORTED: msvc |
9 | |
10 | #define NOINLINE __attribute__((noinline)) |
11 | inline void break_optimization(void *arg) { |
12 | __asm__ __volatile__("" : : "r" (arg) : "memory" ); |
13 | } |
14 | |
15 | NOINLINE static void Frame0(int frame, char *a, char *b, char *c) { |
16 | char s[4] = {0}; |
17 | char *d = s; |
18 | break_optimization(arg: &d); |
19 | switch (frame) { |
20 | case 3: a[5]++; break; |
21 | case 2: b[5]++; break; |
22 | case 1: c[5]++; break; |
23 | case 0: d[5]++; break; |
24 | } |
25 | } |
26 | NOINLINE static void Frame1(int frame, char *a, char *b) { |
27 | char c[4] = {0}; Frame0(frame, a, b, c); |
28 | break_optimization(arg: 0); |
29 | } |
30 | NOINLINE static void Frame2(int frame, char *a) { |
31 | char b[4] = {0}; Frame1(frame, a, b); |
32 | break_optimization(arg: 0); |
33 | } |
34 | NOINLINE static void Frame3(int frame) { |
35 | char a[4] = {0}; Frame2(frame, a); |
36 | break_optimization(arg: 0); |
37 | } |
38 | |
39 | int main(int argc, char **argv) { |
40 | if (argc != 2) return 1; |
41 | Frame3(frame: argv[1][0] - '0'); |
42 | } |
43 | |
44 | // CHECK0: AddressSanitizer: stack-buffer-overflow |
45 | // CHECK0: #0{{.*}}Frame0 |
46 | // CHECK0: #1{{.*}}Frame1 |
47 | // CHECK0: #2{{.*}}Frame2 |
48 | // CHECK0: #3{{.*}}Frame3 |
49 | // CHECK0: is located in stack of thread T0 at offset |
50 | // CHECK0-NEXT: #0{{.*}}Frame0 |
51 | // |
52 | // CHECK1: AddressSanitizer: stack-buffer-overflow |
53 | // CHECK1: is located in stack of thread T0 at offset |
54 | // CHECK1-NEXT: #0{{.*}}Frame1 |
55 | // |
56 | // CHECK2: AddressSanitizer: stack-buffer-overflow |
57 | // CHECK2: is located in stack of thread T0 at offset |
58 | // CHECK2-NEXT: #0{{.*}}Frame2 |
59 | // |
60 | // CHECK3: AddressSanitizer: stack-buffer-overflow |
61 | // CHECK3: is located in stack of thread T0 at offset |
62 | // CHECK3-NEXT: #0{{.*}}Frame3 |
63 | |