1// Make sure we can throw exceptions from work items executed via
2// QueueUserWorkItem.
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
15void ThrowAndCatch();
16
17__declspec(noinline)
18void Throw() {
19  fprintf(stderr, "Throw\n");
20// CHECK: Throw
21  throw 1;
22}
23
24void ThrowAndCatch() {
25  int local;
26  try {
27    Throw();
28  } catch(...) {
29    fprintf(stderr, "Catch\n");
30// CHECK: Catch
31  }
32}
33
34HANDLE done;
35
36DWORD CALLBACK work_item(LPVOID) {
37  ThrowAndCatch();
38  SetEvent(done);
39  return 0;
40}
41
42int main(int argc, char **argv) {
43  done = CreateEvent(0, false, false, "job is done");
44  if (!done)
45    return 1;
46  QueueUserWorkItem(&work_item, nullptr, 0);
47  unsigned wait_result = WaitForSingleObject(done, 10 * 1000);
48  if (wait_result == WAIT_ABANDONED)
49    fprintf(stderr, "Timed out\n");
50  if (wait_result != WAIT_OBJECT_0) {
51    fprintf(stderr, "Wait for work item failed\n");
52    return 2;
53  }
54  fprintf(stderr, "Done!\n");
55// CHECK: Done!
56}
57