1*673dc3d4SNico Weber // Make sure that ASan works with SEH in both Clang and MSVC. MSVC uses a
2*673dc3d4SNico Weber // different EH personality depending on the -GS setting, so test both -GS+ and
3*673dc3d4SNico Weber // -GS-.
4*673dc3d4SNico Weber //
5*673dc3d4SNico Weber // RUN: cl -c %s -Fo%t.obj -DCOMPILE_SEH
6*673dc3d4SNico Weber // RUN: %clangxx_asan -o %t.exe %s %t.obj
7*673dc3d4SNico Weber // RUN: %run %t.exe
8*673dc3d4SNico Weber //
9*673dc3d4SNico Weber // RUN: cl -GS- -c %s -Fo%t.obj -DCOMPILE_SEH
10*673dc3d4SNico Weber // RUN: %clangxx_asan -o %t.exe %s %t.obj
11*673dc3d4SNico Weber // RUN: %run %t.exe
12*673dc3d4SNico Weber //
13*673dc3d4SNico Weber // RUN: %clang_cl_asan %s -DCOMPILE_SEH -Fe%t.exe
14*673dc3d4SNico Weber // RUN: %run %t.exe
15*673dc3d4SNico Weber 
16*673dc3d4SNico Weber #include <windows.h>
17*673dc3d4SNico Weber #include <assert.h>
18*673dc3d4SNico Weber #include <stdio.h>
19*673dc3d4SNico Weber 
20*673dc3d4SNico Weber // Should just "#include <sanitizer/asan_interface.h>" when C++ exceptions are
21*673dc3d4SNico Weber // supported and we don't need to use CL.
22*673dc3d4SNico Weber extern "C" bool __asan_address_is_poisoned(void *p);
23*673dc3d4SNico Weber 
24*673dc3d4SNico Weber void ThrowAndCatch();
25*673dc3d4SNico Weber 
26*673dc3d4SNico Weber #if defined(COMPILE_SEH)
27*673dc3d4SNico Weber __declspec(noinline)
Throw()28*673dc3d4SNico Weber void Throw() {
29*673dc3d4SNico Weber   int local, zero = 0;
30*673dc3d4SNico Weber   fprintf(stderr, "Throw:  %p\n", &local);
31*673dc3d4SNico Weber   local = 5 / zero;
32*673dc3d4SNico Weber }
33*673dc3d4SNico Weber 
34*673dc3d4SNico Weber __declspec(noinline)
ThrowAndCatch()35*673dc3d4SNico Weber void ThrowAndCatch() {
36*673dc3d4SNico Weber   int local;
37*673dc3d4SNico Weber   __try {
38*673dc3d4SNico Weber     Throw();
39*673dc3d4SNico Weber   } __except(EXCEPTION_EXECUTE_HANDLER) {
40*673dc3d4SNico Weber     fprintf(stderr, "__except:  %p\n", &local);
41*673dc3d4SNico Weber   }
42*673dc3d4SNico Weber }
43*673dc3d4SNico Weber #endif
44*673dc3d4SNico Weber 
45*673dc3d4SNico Weber #if defined(__clang__)
main()46*673dc3d4SNico Weber int main() {
47*673dc3d4SNico Weber   char x[32];
48*673dc3d4SNico Weber   fprintf(stderr, "Before: %p poisoned: %d\n", &x,
49*673dc3d4SNico Weber           __asan_address_is_poisoned(x + 32));
50*673dc3d4SNico Weber   assert(__asan_address_is_poisoned(x + 32));
51*673dc3d4SNico Weber   ThrowAndCatch();
52*673dc3d4SNico Weber   fprintf(stderr, "After:  %p poisoned: %d\n",  &x,
53*673dc3d4SNico Weber           __asan_address_is_poisoned(x + 32));
54*673dc3d4SNico Weber   // FIXME: Invert this assertion once we fix
55*673dc3d4SNico Weber   // https://code.google.com/p/address-sanitizer/issues/detail?id=258
56*673dc3d4SNico Weber   assert(!__asan_address_is_poisoned(x + 32));
57*673dc3d4SNico Weber }
58*673dc3d4SNico Weber #endif
59