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