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