1673dc3d4SNico Weber // Test that use-after-return works with exceptions.
2673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t
3673dc3d4SNico Weber // RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t
4*60084d49SKevin Athey // RUN: %clangxx_asan -O0 %s -o %t -fsanitize-address-use-after-return=always
5af8c59e0SKevin Athey // RUN: %run %t
6673dc3d4SNico Weber 
7673dc3d4SNico Weber #include <stdio.h>
8673dc3d4SNico Weber 
9673dc3d4SNico Weber volatile char *g;
10673dc3d4SNico Weber 
11673dc3d4SNico Weber #ifndef FRAME_SIZE
12673dc3d4SNico Weber # define FRAME_SIZE 100
13673dc3d4SNico Weber #endif
14673dc3d4SNico Weber 
15673dc3d4SNico Weber #ifndef NUM_ITER
16673dc3d4SNico Weber # define NUM_ITER 4000
17673dc3d4SNico Weber #endif
18673dc3d4SNico Weber 
19673dc3d4SNico Weber #ifndef DO_THROW
20673dc3d4SNico Weber # define DO_THROW 1
21673dc3d4SNico Weber #endif
22673dc3d4SNico Weber 
Func(int depth)23673dc3d4SNico Weber void Func(int depth) {
24673dc3d4SNico Weber   char frame[FRAME_SIZE];
25673dc3d4SNico Weber   g = &frame[0];
26673dc3d4SNico Weber   if (depth)
27673dc3d4SNico Weber     Func(depth - 1);
28673dc3d4SNico Weber   else if (DO_THROW)
29673dc3d4SNico Weber     throw 1;
30673dc3d4SNico Weber }
31673dc3d4SNico Weber 
main(int argc,char ** argv)32673dc3d4SNico Weber int main(int argc, char **argv) {
33673dc3d4SNico Weber   for (int i = 0; i < NUM_ITER; i++) {
34673dc3d4SNico Weber     try {
35673dc3d4SNico Weber       Func(argc * 100);
36673dc3d4SNico Weber     } catch(...) {
37673dc3d4SNico Weber     }
38673dc3d4SNico Weber     if ((i % (NUM_ITER / 10)) == 0)
39673dc3d4SNico Weber       fprintf(stderr, "done [%d]\n", i);
40673dc3d4SNico Weber   }
41673dc3d4SNico Weber   return 0;
42673dc3d4SNico Weber }
43