130 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -emit-llvm %s -o - | FileCheck %s2 3// CHECK: define dso_local noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"4// CHECK: %coerce.dive1 = getelementptr inbounds nuw %class.B25// CHECK: %coerce.dive2 = getelementptr inbounds nuw %class.B16// ----- scope begin of two passed-by-value temps 7// CHECK: invoke void @llvm.seh.scope.begin()8// CHECK: invoke void @llvm.seh.scope.begin()9// CHECK: invoke void @llvm.seh.scope.end()10// CHECK: call void @"??1B1@@QEAA@XZ"11// CHECK: invoke void @llvm.seh.scope.end()12// CHECK: call void @"??1B2@@QEAA@XZ"13 14// CHECK: define linkonce_odr dso_local void @"??1B2@@QEAA@XZ"15// CHECK: %this.addr = alloca ptr16// ----- B1 scope begin without base ctor17// CHECK: invoke void @llvm.seh.scope.begin()18// CHECK: invoke void @llvm.seh.scope.end()19// CHECK: call void @"??1B1@@QEAA@XZ"20 21// CHECK: define dso_local void @"?goo@@YA?AVB1@@H@Z"22// CHECK: call noundef ptr @"??0B2@@QEAA@XZ"(ptr23// CHECK: invoke void @llvm.seh.scope.begin()24// check: call void @llvm.memcpy25// CHECK: invoke void @llvm.seh.scope.end()26// CHECK: call void @"??1B2@@QEAA@XZ"(ptr27 28// CHECK: define linkonce_odr dso_local noundef ptr @"??0B2@@QEAA@XZ"29// CHECK: call noundef ptr @"??0B1@@QEAA@XZ"(ptr30// ----- scope begin of base ctor 31// CHECK: invoke void @llvm.seh.scope.begin()32// CHECK: invoke void @llvm.seh.scope.end()33// ----- B1 scope end without base dtor34 35// ****************************************************************************36// Abstract: Test CPP Conditional-Expr & ABI Temps under SEH -EHa option37 38void printf(...);39 40int xxxx = 0;41int* ptr; 42 43int foo(int a)44{45 return xxxx + a;46}47 48class B1 {49public:50 int data = 90;51 B1() { foo(data + 111); }52 ~B1() { printf("in B1 Dtor \n"); }53};54class B2 : public B1 {55public:56 B2() { foo(data + 222); }57 ~B2() { printf("in B2 Dtor \n");; }58};59class B3 : public B2 {60public:61 B3() { foo(data + 333); }62 ~B3() { printf("in B3 Dtor \n");; }63};64 65int bar(int j, class B1 b1Bar, class B2 b2Bar)66{67 int ww;68 if ( j > 0)69 ww = b1Bar.data;70 else71 ww = b2Bar.data;72 return ww + *ptr;73}74 75class B1 goo(int w)76{77 class B2 b2ingoo;78 b2ingoo.data += w;79 return b2ingoo;80}81 82// CHECK: define dso_local noundef i32 @main()83// CHECK: invoke void @llvm.seh.scope.begin()84// --- beginning of conditional temp test85// CHECK: invoke noundef ptr @"??0B2@@QEAA@XZ"86// CHECK: invoke void @llvm.seh.scope.begin()87// CHECK: invoke noundef ptr @"??0B3@@QEAA@XZ"88// CHECK: invoke void @llvm.seh.scope.begin()89// CHECK: invoke void @llvm.seh.scope.end()90// CHECK: call void @"??1B3@@QEAA@XZ"91// CHECK: invoke void @llvm.seh.scope.end()92// CHECK: call void @"??1B2@@QEAA@XZ"93// ----- end of conditional temp test94 95// ----- testing caller's passed-by-value temps96// setting scope in case exception occurs before the call97// check: invoke ptr @"??0B2@@QEAA@XZ"98// CHECK: invoke void @llvm.seh.scope.begin()99// CHECK: invoke noundef ptr @"??0B1@@QEAA@XZ"100// CHECK: invoke void @llvm.seh.scope.begin()101// ----- end of temps' scope right before callee102// CHECK: invoke void @llvm.seh.scope.end()103// CHECK: invoke void @llvm.seh.scope.end()104// CHECK: invoke noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"105 106// ----- testing caller's return-by-value temp107// scope begins right after callee which is the ctor of return temp108// CHECK: void @"?goo@@YA?AVB1@@H@Z"109// CHECK: invoke void @llvm.seh.scope.begin()110// CHECK: invoke void @llvm.seh.scope.end()111 112int main() {113 class B3 b3inmain;114 115 // Test conditional ctor and dtor116 int m = (xxxx > 1) ? B2().data + foo(99) : 117 B3().data + foo(88);118 119 // Test: passed-in by value120 // Per Windows ABI, ctored by caller, dtored by callee121 int i = bar(foo(0), B1(), B2());122 123 // Test: returned by value124 // Per Windows ABI, caller allocate a temp in stack, then ctored by callee, 125 // finally dtored in caller after consumed126 class B1 b1fromgoo = goo(i);127 128 return m + b1fromgoo.data + b3inmain.data;129}130