178 lines · 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=CXXEH4// 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-passes | \6// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX7 8extern "C" unsigned long _exception_code();9extern "C" void might_throw();10 11struct HasCleanup {12 HasCleanup();13 ~HasCleanup();14 int padding;15};16 17extern "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 dso_local void @use_cxx()25// CXXEH-SAME: personality ptr @__CxxFrameHandler326// CXXEH: call noundef ptr @"??0HasCleanup@@QEAA@XZ"(ptr {{[^,]*}} %{{.*}})27// CXXEH: invoke void @might_throw()28// CXXEH: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]29//30// CXXEH: [[cont]]31// CXXEH: call void @"??1HasCleanup@@QEAA@XZ"(ptr {{[^,]*}} %{{.*}})32// CXXEH: ret void33//34// CXXEH: [[lpad]]35// CXXEH: cleanuppad36// CXXEH: call void @"??1HasCleanup@@QEAA@XZ"(ptr {{[^,]*}} %{{.*}})37// CXXEH: cleanupret38 39// NOCXX-LABEL: define dso_local void @use_cxx()40// NOCXX-NOT: invoke41// NOCXX: call noundef ptr @"??0HasCleanup@@QEAA@XZ"(ptr {{[^,]*}} %{{.*}})42// NOCXX-NOT: invoke43// NOCXX: call void @might_throw()44// NOCXX-NOT: invoke45// NOCXX: call void @"??1HasCleanup@@QEAA@XZ"(ptr {{[^,]*}} %{{.*}})46// NOCXX-NOT: invoke47// NOCXX: ret void48 49extern "C" void use_seh() {50 __try {51 might_throw();52 } __except(1) {53 }54}55 56// Make sure we use __C_specific_handler for SEH.57 58// CHECK-LABEL: define dso_local void @use_seh()59// CHECK-SAME: personality ptr @__C_specific_handler60// CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]61// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]62//63// CHECK: [[lpad]]64// CHECK-NEXT: %[[switch:.*]] = catchswitch within none [label %[[cpad:.*]]] unwind to caller65//66// CHECK: [[cpad]]67// CHECK-NEXT: catchpad within %[[switch]]68// CHECK: catchret {{.*}} label %[[except:[^ ]*]]69//70// CHECK: [[except]]71// CHECK: br label %[[ret:[^ ]*]]72//73// CHECK: [[ret]]74// CHECK: ret void75//76// CHECK: [[cont]]77// CHECK: br label %[[ret]]78 79extern "C" void nested_finally() {80 __try {81 might_throw();82 } __finally {83 __try {84 might_throw();85 } __finally {86 }87 }88}89 90// CHECK-LABEL: define dso_local void @nested_finally() #{{[0-9]+}}91// CHECK-SAME: personality ptr @__C_specific_handler92// CHECK: invoke void @might_throw()93// CHECK: call void @"?fin$0@0@nested_finally@@"(i8 noundef 1, ptr {{.*}})94 95// CHECK-LABEL: define internal void @"?fin$0@0@nested_finally@@"96// CHECK-SAME: personality ptr @__C_specific_handler97// CHECK: invoke void @might_throw()98// CHECK: call void @"?fin$1@0@nested_finally@@"(i8 noundef 1, ptr {{.*}})99 100void use_seh_in_lambda() {101 ([]() {102 __try {103 might_throw();104 } __except(1) {105 }106 })();107 HasCleanup x;108 might_throw();109}110 111// CXXEH-LABEL: define dso_local void @"?use_seh_in_lambda@@YAXXZ"()112// CXXEH-SAME: personality ptr @__CxxFrameHandler3113// CXXEH: cleanuppad114 115// NOCXX-LABEL: define dso_local void @"?use_seh_in_lambda@@YAXXZ"()116// NOCXX-NOT: invoke117// NOCXX: ret void118 119// CHECK-LABEL: define internal void @"??R<lambda_0>@?0??use_seh_in_lambda@@YAXXZ@QEBA@XZ"(ptr {{[^,]*}} %this)120// CXXEH-SAME: personality ptr @__C_specific_handler121// CHECK: invoke void @might_throw() #[[NOINLINE]]122// CHECK: catchpad123 124class use_seh_in_constructor { use_seh_in_constructor(); };125use_seh_in_constructor::use_seh_in_constructor(){126 __try {127 } __finally {128 }129}130 131// CHECK: define internal void @"?fin$0@0@?0use_seh_in_constructor@@"132 133static int my_unique_global;134 135extern "C" inline void use_seh_in_inline_func() {136 __try {137 might_throw();138 } __except(_exception_code() == 424242) {139 }140 __try {141 might_throw();142 } __finally {143 my_unique_global = 1234;144 }145}146 147void use_inline() {148 use_seh_in_inline_func();149}150 151// CHECK-LABEL: define linkonce_odr dso_local void @use_seh_in_inline_func() #{{[0-9]+}}152// CHECK-SAME: personality ptr @__C_specific_handler153// CHECK: invoke void @might_throw()154//155// CHECK: catchpad {{.*}} [ptr @"?filt$0@0@use_seh_in_inline_func@@"]156//157// CHECK: invoke void @might_throw()158//159// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()160// CHECK: call void @"?fin$0@0@use_seh_in_inline_func@@"(i8 noundef 0, ptr noundef %[[fp]])161// CHECK: ret void162//163// CHECK: cleanuppad164// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()165// CHECK: call void @"?fin$0@0@use_seh_in_inline_func@@"(i8 noundef 1, ptr noundef %[[fp]])166 167// CHECK-LABEL: define internal noundef i32 @"?filt$0@0@use_seh_in_inline_func@@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer) #{{[0-9]+}}168// CHECK: icmp eq i32 %{{.*}}, 424242169// CHECK: zext i1 %{{.*}} to i32170// CHECK: ret i32171 172// CHECK-LABEL: define internal void @"?fin$0@0@use_seh_in_inline_func@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer) #{{[0-9]+}}173// CHECK: store i32 1234, ptr @my_unique_global174 175// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }176 177void seh_in_noexcept() noexcept { __try {} __finally {} }178