1 // Make sure we can throw exceptions from work items executed via
2 // BindIoCompletionCallback.
3 //
4 // Clang doesn't support exceptions on Windows yet, so for the time being we
5 // build this program in two parts: the code with exceptions is built with CL,
6 // the rest is built with Clang. This represents the typical scenario when we
7 // build a large project using "clang-cl -fallback -fsanitize=address".
8 //
9 // RUN: cl -c %s -Fo%t.obj
10 // RUN: %clangxx_asan -o %t.exe %s %t.obj
11 // RUN: %run %t.exe 2>&1 | FileCheck %s
12
13 #include <windows.h>
14 #include <stdio.h>
15
16 void ThrowAndCatch();
17
18 #if !defined(__clang__)
19 __declspec(noinline)
Throw()20 void Throw() {
21 fprintf(stderr, "Throw\n");
22 // CHECK: Throw
23 throw 1;
24 }
25
ThrowAndCatch()26 void ThrowAndCatch() {
27 int local;
28 try {
29 Throw();
30 } catch(...) {
31 fprintf(stderr, "Catch\n");
32 // CHECK: Catch
33 }
34 }
35 #else
36
37 char buffer[65536];
38 HANDLE done;
39 OVERLAPPED ov;
40
completion_callback(DWORD error,DWORD bytesRead,LPOVERLAPPED pov)41 void CALLBACK completion_callback(DWORD error, DWORD bytesRead,
42 LPOVERLAPPED pov) {
43 ThrowAndCatch();
44 SetEvent(done);
45 }
46
main(int argc,char ** argv)47 int main(int argc, char **argv) {
48 done = CreateEvent(0, false, false, "job is done");
49 if (!done)
50 return 1;
51 HANDLE file = CreateFile(
52 argv[0], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
53 OPEN_EXISTING,
54 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
55 NULL);
56 if (!file)
57 return 2;
58 if (!BindIoCompletionCallback(file, completion_callback, 0))
59 return 3;
60
61 if (!ReadFile(file, buffer, sizeof(buffer), NULL, &ov) &&
62 GetLastError() != ERROR_IO_PENDING)
63 return 4;
64
65 if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE))
66 return 5;
67 fprintf(stderr, "Done!\n");
68 // CHECK: Done!
69 }
70 #endif
71