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) 20 void Throw() { 21 fprintf(stderr, "Throw\n"); 22 // CHECK: Throw 23 throw 1; 24 } 25 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 41 void CALLBACK completion_callback(DWORD error, DWORD bytesRead, 42 LPOVERLAPPED pov) { 43 ThrowAndCatch(); 44 SetEvent(done); 45 } 46 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