1*673dc3d4SNico Weber // Make sure we can throw exceptions from work items executed via
2*673dc3d4SNico Weber // QueueUserWorkItem.
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 HANDLE done;
30*673dc3d4SNico Weber 
work_item(LPVOID)31*673dc3d4SNico Weber DWORD CALLBACK work_item(LPVOID) {
32*673dc3d4SNico Weber   ThrowAndCatch();
33*673dc3d4SNico Weber   SetEvent(done);
34*673dc3d4SNico Weber   return 0;
35*673dc3d4SNico Weber }
36*673dc3d4SNico Weber 
main(int argc,char ** argv)37*673dc3d4SNico Weber int main(int argc, char **argv) {
38*673dc3d4SNico Weber   done = CreateEvent(0, false, false, "job is done");
39*673dc3d4SNico Weber   if (!done)
40*673dc3d4SNico Weber     return 1;
41*673dc3d4SNico Weber   QueueUserWorkItem(&work_item, nullptr, 0);
42*673dc3d4SNico Weber   unsigned wait_result = WaitForSingleObject(done, 10 * 1000);
43*673dc3d4SNico Weber   if (wait_result == WAIT_ABANDONED)
44*673dc3d4SNico Weber     fprintf(stderr, "Timed out\n");
45*673dc3d4SNico Weber   if (wait_result != WAIT_OBJECT_0) {
46*673dc3d4SNico Weber     fprintf(stderr, "Wait for work item failed\n");
47*673dc3d4SNico Weber     return 2;
48*673dc3d4SNico Weber   }
49*673dc3d4SNico Weber   fprintf(stderr, "Done!\n");
50*673dc3d4SNico Weber // CHECK: Done!
51*673dc3d4SNico Weber }
52