]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenCXX/exceptions-seh.cpp
Vendor import of clang trunk r238337:
[FreeBSD/FreeBSD.git] / test / CodeGenCXX / exceptions-seh.cpp
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" unsigned long _exception_code();
9 extern "C" void might_throw();
10
11 struct HasCleanup {
12   HasCleanup();
13   ~HasCleanup();
14   int padding;
15 };
16
17 extern "C" void use_cxx() {
18   HasCleanup x;
19   might_throw();
20 }
21
22 // Make sure we use __CxxFrameHandler3 for C++ EH.
23
24 // CXXEH-LABEL: define void @use_cxx()
25 // CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
26 // CXXEH: invoke void @might_throw()
27 // CXXEH:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
28 //
29 // CXXEH: [[cont]]
30 // CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
31 // CXXEH: ret void
32 //
33 // CXXEH: [[lpad]]
34 // CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
35 // CXXEH-NEXT: cleanup
36 // CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
37 // CXXEH: br label %[[resume:[^ ]*]]
38 //
39 // CXXEH: [[resume]]
40 // CXXEH: resume
41
42 // NOCXX-LABEL: define void @use_cxx()
43 // NOCXX-NOT: invoke
44 // NOCXX: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
45 // NOCXX-NOT: invoke
46 // NOCXX: call void @might_throw()
47 // NOCXX-NOT: invoke
48 // NOCXX: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
49 // NOCXX-NOT: invoke
50 // NOCXX: ret void
51
52 extern "C" void use_seh() {
53   __try {
54     might_throw();
55   } __except(1) {
56   }
57 }
58
59 // Make sure we use __C_specific_handler for SEH.
60
61 // CHECK-LABEL: define void @use_seh()
62 // CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
63 // CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
64 //
65 // CHECK: [[cont]]
66 // CHECK: br label %[[ret:[^ ]*]]
67 //
68 // CHECK: [[lpad]]
69 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
70 // CHECK-NEXT: catch i8*
71 //
72 // CHECK: br label %[[ret]]
73 //
74 // CHECK: [[ret]]
75 // CHECK: ret void
76
77 void use_seh_in_lambda() {
78   ([]() {
79     __try {
80       might_throw();
81     } __except(1) {
82     }
83   })();
84   HasCleanup x;
85   might_throw();
86 }
87
88 // CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
89 // CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
90
91 // NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
92 // NOCXX-NOT: invoke
93 // NOCXX: ret void
94
95 // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)
96 // CHECK: invoke void @might_throw() #[[NOINLINE]]
97 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
98
99 static int my_unique_global;
100
101 extern "C" inline void use_seh_in_inline_func() {
102   __try {
103     might_throw();
104   } __except(_exception_code() == 424242) {
105   }
106   __try {
107     might_throw();
108   } __finally {
109     my_unique_global = 1234;
110   }
111 }
112
113 void use_inline() {
114   use_seh_in_inline_func();
115 }
116
117 // CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat {
118 // CHECK: invoke void @might_throw()
119 //
120 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
121 // CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_seh_in_inline_func@@" to i8*)
122 //
123 // CHECK: invoke void @might_throw()
124 //
125 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
126 // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]])
127 // CHECK: ret void
128 //
129 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
130 // CHECK-NEXT: cleanup
131 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
132 // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]])
133
134 // CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func)
135 // CHECK: icmp eq i32 %{{.*}}, 424242
136 // CHECK: zext i1 %{{.*}} to i32
137 // CHECK: ret i32
138
139 // CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func)
140 // CHECK: store i32 1234, i32* @my_unique_global
141
142 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }