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