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: 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