1*673dc3d4SNico Weber // Check that we can store lots of stack frames if asked to.
2*673dc3d4SNico Weber 
3*673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t 2>&1
4*673dc3d4SNico Weber // RUN: %env_asan_opts=malloc_context_size=120:redzone=512 not %run %t 2>&1 | FileCheck %s
5*673dc3d4SNico Weber // REQUIRES: stable-runtime
6*673dc3d4SNico Weber #include <stdlib.h>
7*673dc3d4SNico Weber #include <stdio.h>
8*673dc3d4SNico Weber 
9*673dc3d4SNico Weber template <int depth>
10*673dc3d4SNico Weber struct DeepFree {
freeDeepFree11*673dc3d4SNico Weber   static void free(char *x) {
12*673dc3d4SNico Weber     DeepFree<depth - 1>::free(x);
13*673dc3d4SNico Weber   }
14*673dc3d4SNico Weber };
15*673dc3d4SNico Weber 
16*673dc3d4SNico Weber template<>
17*673dc3d4SNico Weber struct DeepFree<0> {
freeDeepFree18*673dc3d4SNico Weber   static void free(char *x) {
19*673dc3d4SNico Weber     ::free(x);
20*673dc3d4SNico Weber   }
21*673dc3d4SNico Weber };
22*673dc3d4SNico Weber 
main()23*673dc3d4SNico Weber int main() {
24*673dc3d4SNico Weber   char *x = (char*)malloc(10);
25*673dc3d4SNico Weber   // deep_free(x);
26*673dc3d4SNico Weber   DeepFree<200>::free(x);
27*673dc3d4SNico Weber   return x[5];
28*673dc3d4SNico Weber   // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
29*673dc3d4SNico Weber   // The libcxxrt demangling procedure on FreeBSD 9.2 incorrectly appends
30*673dc3d4SNico Weber   // extra 'E' characters to the end of template arguments; see:
31*673dc3d4SNico Weber   // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192115
32*673dc3d4SNico Weber   // CHECK: {{DeepFree<36>|DeepFree<36E>}}
33*673dc3d4SNico Weber   // CHECK: {{DeepFree<98>|DeepFree<98E>}}
34*673dc3d4SNico Weber   // CHECK: {{DeepFree<115>|DeepFree<115E>}}
35*673dc3d4SNico Weber }
36