1*673dc3d4SNico Weber // Make sure we can throw exceptions from work items executed via
2*673dc3d4SNico Weber // BindIoCompletionCallback.
3*673dc3d4SNico Weber //
4*673dc3d4SNico Weber // RUN: %clangxx_asan %s -o %t.exe
5*673dc3d4SNico Weber // RUN: %run %t.exe 2>&1 | FileCheck %s
6*673dc3d4SNico Weber
7*673dc3d4SNico Weber #include <windows.h>
8*673dc3d4SNico Weber #include <stdio.h>
9*673dc3d4SNico Weber
10*673dc3d4SNico Weber void ThrowAndCatch();
11*673dc3d4SNico Weber
12*673dc3d4SNico Weber __declspec(noinline)
Throw()13*673dc3d4SNico Weber void Throw() {
14*673dc3d4SNico Weber fprintf(stderr, "Throw\n");
15*673dc3d4SNico Weber // CHECK: Throw
16*673dc3d4SNico Weber throw 1;
17*673dc3d4SNico Weber }
18*673dc3d4SNico Weber
ThrowAndCatch()19*673dc3d4SNico Weber void ThrowAndCatch() {
20*673dc3d4SNico Weber int local;
21*673dc3d4SNico Weber try {
22*673dc3d4SNico Weber Throw();
23*673dc3d4SNico Weber } catch(...) {
24*673dc3d4SNico Weber fprintf(stderr, "Catch\n");
25*673dc3d4SNico Weber // CHECK: Catch
26*673dc3d4SNico Weber }
27*673dc3d4SNico Weber }
28*673dc3d4SNico Weber
29*673dc3d4SNico Weber char buffer[65536];
30*673dc3d4SNico Weber HANDLE done;
31*673dc3d4SNico Weber OVERLAPPED ov;
32*673dc3d4SNico Weber
completion_callback(DWORD error,DWORD bytesRead,LPOVERLAPPED pov)33*673dc3d4SNico Weber void CALLBACK completion_callback(DWORD error, DWORD bytesRead,
34*673dc3d4SNico Weber LPOVERLAPPED pov) {
35*673dc3d4SNico Weber ThrowAndCatch();
36*673dc3d4SNico Weber SetEvent(done);
37*673dc3d4SNico Weber }
38*673dc3d4SNico Weber
main(int argc,char ** argv)39*673dc3d4SNico Weber int main(int argc, char **argv) {
40*673dc3d4SNico Weber done = CreateEvent(0, false, false, "job is done");
41*673dc3d4SNico Weber if (!done)
42*673dc3d4SNico Weber return 1;
43*673dc3d4SNico Weber HANDLE file = CreateFile(
44*673dc3d4SNico Weber argv[0], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
45*673dc3d4SNico Weber OPEN_EXISTING,
46*673dc3d4SNico Weber FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
47*673dc3d4SNico Weber NULL);
48*673dc3d4SNico Weber if (!file)
49*673dc3d4SNico Weber return 2;
50*673dc3d4SNico Weber if (!BindIoCompletionCallback(file, completion_callback, 0))
51*673dc3d4SNico Weber return 3;
52*673dc3d4SNico Weber
53*673dc3d4SNico Weber if (!ReadFile(file, buffer, sizeof(buffer), NULL, &ov) &&
54*673dc3d4SNico Weber GetLastError() != ERROR_IO_PENDING)
55*673dc3d4SNico Weber return 4;
56*673dc3d4SNico Weber
57*673dc3d4SNico Weber if (WAIT_OBJECT_0 != WaitForSingleObject(done, 10 * 1000))
58*673dc3d4SNico Weber return 5;
59*673dc3d4SNico Weber fprintf(stderr, "Done!\n");
60*673dc3d4SNico Weber // CHECK: Done!
61*673dc3d4SNico Weber }
62