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