forked from OSchip/llvm-project
129 lines
4.1 KiB
C++
129 lines
4.1 KiB
C++
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
|
|
|
|
// CHECK: define dso_local noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"
|
|
// CHECK: %coerce.dive1 = getelementptr inbounds %class.B2
|
|
// CHECK: %coerce.dive2 = getelementptr inbounds %class.B1
|
|
// ----- scope begin of two passed-by-value temps
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B1@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B2@@QEAA@XZ"
|
|
|
|
// CHECK: define linkonce_odr dso_local void @"??1B2@@QEAA@XZ"
|
|
// CHECK: %this.addr = alloca %class.B2*
|
|
// ----- B1 scope begin without base ctor
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B1@@QEAA@XZ"
|
|
|
|
// CHECK: define dso_local void @"?goo@@YA?AVB1@@H@Z"
|
|
// CHECK: call noundef %class.B2* @"??0B2@@QEAA@XZ"(%class.B2*
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// check: call void @llvm.memcpy
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B2@@QEAA@XZ"(%class.B2*
|
|
|
|
// CHECK: define linkonce_odr dso_local noundef %class.B2* @"??0B2@@QEAA@XZ"
|
|
// CHECK: call noundef %class.B1* @"??0B1@@QEAA@XZ"(%class.B1*
|
|
// ----- scope begin of base ctor
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// ----- B1 scope end without base dtor
|
|
|
|
// ****************************************************************************
|
|
// Abstract: Test CPP Conditional-Expr & ABI Temps under SEH -EHa option
|
|
|
|
void printf(...);
|
|
|
|
int xxxx = 0;
|
|
int* ptr;
|
|
|
|
int foo(int a)
|
|
{
|
|
return xxxx + a;
|
|
}
|
|
|
|
class B1 {
|
|
public:
|
|
int data = 90;
|
|
B1() { foo(data + 111); }
|
|
~B1() { printf("in B1 Dtor \n"); }
|
|
};
|
|
class B2 : public B1 {
|
|
public:
|
|
B2() { foo(data + 222); }
|
|
~B2() { printf("in B2 Dtor \n");; }
|
|
};
|
|
class B3 : public B2 {
|
|
public:
|
|
B3() { foo(data + 333); }
|
|
~B3() { printf("in B3 Dtor \n");; }
|
|
};
|
|
|
|
int bar(int j, class B1 b1Bar, class B2 b2Bar)
|
|
{
|
|
int ww;
|
|
if ( j > 0)
|
|
ww = b1Bar.data;
|
|
else
|
|
ww = b2Bar.data;
|
|
return ww + *ptr;
|
|
}
|
|
|
|
class B1 goo(int w)
|
|
{
|
|
class B2 b2ingoo;
|
|
b2ingoo.data += w;
|
|
return b2ingoo;
|
|
}
|
|
|
|
// CHECK: define dso_local noundef i32 @main()
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// --- beginning of conditional temp test
|
|
// CHECK: invoke noundef %class.B2* @"??0B2@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke noundef %class.B3* @"??0B3@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B3@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: call void @"??1B2@@QEAA@XZ"
|
|
// ----- end of conditional temp test
|
|
|
|
// ----- testing caller's passed-by-value temps
|
|
// setting scope in case exception occurs before the call
|
|
// check: invoke %class.B2* @"??0B2@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke noundef %class.B1* @"??0B1@@QEAA@XZ"
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// ----- end of temps' scope right before callee
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
// CHECK: invoke noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"
|
|
|
|
// ----- testing caller's return-by-value temp
|
|
// scope begins right after callee which is the ctor of return temp
|
|
// CHECK: void @"?goo@@YA?AVB1@@H@Z"
|
|
// CHECK: invoke void @llvm.seh.scope.begin()
|
|
// CHECK: invoke void @llvm.seh.scope.end()
|
|
|
|
int main() {
|
|
class B3 b3inmain;
|
|
|
|
// Test conditional ctor and dtor
|
|
int m = (xxxx > 1) ? B2().data + foo(99) :
|
|
B3().data + foo(88);
|
|
|
|
// Test: passed-in by value
|
|
// Per Windows ABI, ctored by caller, dtored by callee
|
|
int i = bar(foo(0), B1(), B2());
|
|
|
|
// Test: returned by value
|
|
// Per Windows ABI, caller allocate a temp in stack, then ctored by callee,
|
|
// finally dtored in caller after consumed
|
|
class B1 b1fromgoo = goo(i);
|
|
|
|
return m + b1fromgoo.data + b3inmain.data;
|
|
} |