1 // RUN: %clangxx -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
2 
3 // REQUIRES: stable-runtime
4 
5 // XFAIL: ubsan
6 // FIXME: On Darwin, LSAn detects the leak, but does not invoke the death_callback.
7 // XFAIL: darwin && lsan
8 
9 #include <sanitizer/common_interface_defs.h>
10 #include <stdio.h>
11 
12 volatile char *zero = 0;
13 
Death()14 void Death() {
15   fprintf(stderr, "DEATH CALLBACK EXECUTED\n");
16 }
17 // CHECK: DEATH CALLBACK EXECUTED
18 
19 char global;
20 volatile char *sink;
21 
22 __attribute__((noinline))
MaybeInit(int * uninitialized)23 void MaybeInit(int *uninitialized) {
24   if (zero)
25     *uninitialized = 1;
26 }
27 
28 __attribute__((noinline))
Leak()29 void Leak() {
30   // Trigger lsan report. Two attempts in case the address of the first
31   // allocation remained on the stack.
32   sink = new char[100];
33   sink = new char[100];
34 }
35 
main(int argc,char ** argv)36 int main(int argc, char **argv) {
37   int uninitialized;
38   __sanitizer_set_death_callback(Death);
39   MaybeInit(&uninitialized);
40   if (uninitialized)  // trigger msan report.
41     global = 77;
42   sink = new char[100];
43   delete[] sink;
44   global = sink[0];  // use-after-free: trigger asan/tsan report.
45   Leak();
46   sink = 0;
47 }
48