1 // RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
2 // RUN:         -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
3 // RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
4 // RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
5 // RUN:         -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \
6 // RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
7 
8 extern "C" void might_throw();
9 
10 struct HasCleanup {
11   HasCleanup();
12   ~HasCleanup();
13   int padding;
14 };
15 
16 extern "C" void use_cxx() {
17   HasCleanup x;
18   might_throw();
19 }
20 
21 // Make sure we use __CxxFrameHandler3 for C++ EH.
22 
23 // CXXEH-LABEL: define void @use_cxx()
24 // CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
25 // CXXEH: invoke void @might_throw()
26 // CXXEH:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
27 //
28 // CXXEH: [[cont]]
29 // CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
30 // CXXEH: ret void
31 //
32 // CXXEH: [[lpad]]
33 // CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
34 // CXXEH-NEXT: cleanup
35 // CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
36 // CXXEH: br label %[[resume:[^ ]*]]
37 //
38 // CXXEH: [[resume]]
39 // CXXEH: resume
40 
41 // NOCXX-LABEL: define void @use_cxx()
42 // NOCXX-NOT: invoke
43 // NOCXX: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
44 // NOCXX-NOT: invoke
45 // NOCXX: call void @might_throw()
46 // NOCXX-NOT: invoke
47 // NOCXX: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
48 // NOCXX-NOT: invoke
49 // NOCXX: ret void
50 
51 extern "C" void use_seh() {
52   __try {
53     might_throw();
54   } __except(1) {
55   }
56 }
57 
58 // Make sure we use __C_specific_handler for SEH.
59 
60 // CHECK-LABEL: define void @use_seh()
61 // CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
62 // CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
63 //
64 // CHECK: [[cont]]
65 // CHECK: br label %[[ret:[^ ]*]]
66 //
67 // CHECK: [[lpad]]
68 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
69 // CHECK-NEXT: catch i8*
70 //
71 // CHECK: br label %[[ret]]
72 //
73 // CHECK: [[ret]]
74 // CHECK: ret void
75 
76 void use_seh_in_lambda() {
77   ([]() {
78     __try {
79       might_throw();
80     } __except(1) {
81     }
82   })();
83   HasCleanup x;
84   might_throw();
85 }
86 
87 // CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
88 // CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
89 
90 // NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
91 // NOCXX-NOT: invoke
92 // NOCXX: ret void
93 
94 // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)
95 // CHECK: invoke void @might_throw() #[[NOINLINE]]
96 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
97 
98 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
99