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 Webervoid 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 Weberint 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