1 // Clang doesn't support exceptions on Windows yet, so for the time being we
2 // build this program in two parts: the code with exceptions is built with CL,
3 // the rest is built with Clang.  This represents the typical scenario when we
4 // build a large project using "clang-cl -fallback -fsanitize=address".
5 //
6 // RUN: cl -c %s -Fo%t.obj
7 // RUN: %clangxx_asan -o %t.exe %s %t.obj
8 // RUN: %run %t.exe
9 
10 #include <assert.h>
11 #include <stdio.h>
12 
13 // Should just "#include <sanitizer/asan_interface.h>" when C++ exceptions are
14 // supported and we don't need to use CL.
15 extern "C" bool __asan_address_is_poisoned(void *p);
16 
17 void ThrowAndCatch();
18 void TestThrowInline();
19 
20 #if !defined(__clang__)
21 __declspec(noinline)
Throw()22 void Throw() {
23   int local;
24   fprintf(stderr, "Throw:  %p\n", &local);
25   throw 1;
26 }
27 
28 __declspec(noinline)
ThrowAndCatch()29 void ThrowAndCatch() {
30   int local;
31   try {
32     Throw();
33   } catch(...) {
34     fprintf(stderr, "Catch:  %p\n", &local);
35   }
36 }
37 
TestThrowInline()38 void TestThrowInline() {
39   char x[32];
40   fprintf(stderr, "Before: %p poisoned: %d\n", &x,
41           __asan_address_is_poisoned(x + 32));
42   try {
43     Throw();
44   } catch(...) {
45     fprintf(stderr, "Catch\n");
46   }
47   fprintf(stderr, "After:  %p poisoned: %d\n",  &x,
48           __asan_address_is_poisoned(x + 32));
49   // FIXME: Invert this assertion once we fix
50   // https://code.google.com/p/address-sanitizer/issues/detail?id=258
51   assert(!__asan_address_is_poisoned(x + 32));
52 }
53 
54 #else
55 
TestThrow()56 void TestThrow() {
57   char x[32];
58   fprintf(stderr, "Before: %p poisoned: %d\n", &x,
59           __asan_address_is_poisoned(x + 32));
60   assert(__asan_address_is_poisoned(x + 32));
61   ThrowAndCatch();
62   fprintf(stderr, "After:  %p poisoned: %d\n",  &x,
63           __asan_address_is_poisoned(x + 32));
64   // FIXME: Invert this assertion once we fix
65   // https://code.google.com/p/address-sanitizer/issues/detail?id=258
66   assert(!__asan_address_is_poisoned(x + 32));
67 }
68 
main(int argc,char ** argv)69 int main(int argc, char **argv) {
70   TestThrowInline();
71   TestThrow();
72 }
73 #endif
74