189de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany// Test that use-after-return works with exceptions.
2cf2cabb752ffeff152ed471fa407a415c404d6e4Kostya Serebryany// export ASAN_OPTIONS=detect_stack_use_after_return=1
32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %clangxx_asan  -O0 %s -o %t && %run %t
489de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany
55d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// Clang doesn't support exceptions on Windows yet.
65d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// XFAIL: win32
75d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
889de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany#include <stdio.h>
989de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany
1089de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryanyvolatile char *g;
1189de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany
12b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#ifndef FRAME_SIZE
13b1173c27c2791aef27304e68911a11648401064dKostya Serebryany# define FRAME_SIZE 100
14b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#endif
15b1173c27c2791aef27304e68911a11648401064dKostya Serebryany
16b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#ifndef NUM_ITER
17b1173c27c2791aef27304e68911a11648401064dKostya Serebryany# define NUM_ITER 4000
18b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#endif
19b1173c27c2791aef27304e68911a11648401064dKostya Serebryany
20b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#ifndef DO_THROW
21b1173c27c2791aef27304e68911a11648401064dKostya Serebryany# define DO_THROW 1
22b1173c27c2791aef27304e68911a11648401064dKostya Serebryany#endif
23b1173c27c2791aef27304e68911a11648401064dKostya Serebryany
2489de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryanyvoid Func(int depth) {
25b1173c27c2791aef27304e68911a11648401064dKostya Serebryany  char frame[FRAME_SIZE];
2689de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany  g = &frame[0];
2789de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany  if (depth)
2889de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany    Func(depth - 1);
29b1173c27c2791aef27304e68911a11648401064dKostya Serebryany  else if (DO_THROW)
3089de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany    throw 1;
3189de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany}
3289de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany
3389de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryanyint main(int argc, char **argv) {
34b1173c27c2791aef27304e68911a11648401064dKostya Serebryany  for (int i = 0; i < NUM_ITER; i++) {
3589de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany    try {
3689de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany      Func(argc * 100);
3789de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany    } catch(...) {
3889de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany    }
39b1173c27c2791aef27304e68911a11648401064dKostya Serebryany    if ((i % (NUM_ITER / 10)) == 0)
4089de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany      fprintf(stderr, "done [%d]\n", i);
4189de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany  }
4289de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany  return 0;
4389de457bd3ec40d38bc7860f88f1d4da473eacc4Kostya Serebryany}
44