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 %s
3 // CHECK: define dso_local noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"
4 // CHECK: %coerce.dive1 = getelementptr inbounds nuw %class.B2
5 // CHECK: %coerce.dive2 = getelementptr inbounds nuw %class.B1
6 // ----- 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"
14 // CHECK: define linkonce_odr dso_local void @"??1B2@@QEAA@XZ"
15 // CHECK: %this.addr = alloca ptr
16 // ----- B1 scope begin without base ctor
17 // CHECK: invoke void @llvm.seh.scope.begin()
18 // CHECK: invoke void @llvm.seh.scope.end()
19 // CHECK: call void @"??1B1@@QEAA@XZ"
21 // CHECK: define dso_local void @"?goo@@YA?AVB1@@H@Z"
22 // CHECK: call noundef ptr @"??0B2@@QEAA@XZ"(ptr
23 // CHECK: invoke void @llvm.seh.scope.begin()
24 // check: call void @llvm.memcpy
25 // CHECK: invoke void @llvm.seh.scope.end()
26 // CHECK: call void @"??1B2@@QEAA@XZ"(ptr
28 // CHECK: define linkonce_odr dso_local noundef ptr @"??0B2@@QEAA@XZ"
29 // CHECK: call noundef ptr @"??0B1@@QEAA@XZ"(ptr
30 // ----- 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 dtor
35 // ****************************************************************************
36 // Abstract: Test CPP Conditional-Expr & ABI Temps under SEH -EHa option
51 B1() { foo(data
+ 111); }
52 ~B1() { printf("in B1 Dtor \n"); }
54 class B2
: public B1
{
56 B2() { foo(data
+ 222); }
57 ~B2() { printf("in B2 Dtor \n");; }
59 class B3
: public B2
{
61 B3() { foo(data
+ 333); }
62 ~B3() { printf("in B3 Dtor \n");; }
65 int bar(int j
, class B1 b1Bar
, class B2 b2Bar
)
82 // CHECK: define dso_local noundef i32 @main()
83 // CHECK: invoke void @llvm.seh.scope.begin()
84 // --- beginning of conditional temp test
85 // 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 test
95 // ----- testing caller's passed-by-value temps
96 // setting scope in case exception occurs before the call
97 // 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 callee
102 // CHECK: invoke void @llvm.seh.scope.end()
103 // CHECK: invoke void @llvm.seh.scope.end()
104 // CHECK: invoke noundef i32 @"?bar@@YAHHVB1@@VB2@@@Z"
106 // ----- testing caller's return-by-value temp
107 // scope begins right after callee which is the ctor of return temp
108 // CHECK: void @"?goo@@YA?AVB1@@H@Z"
109 // CHECK: invoke void @llvm.seh.scope.begin()
110 // CHECK: invoke void @llvm.seh.scope.end()
115 // Test conditional ctor and dtor
116 int m
= (xxxx
> 1) ? B2().data
+ foo(99) :
119 // Test: passed-in by value
120 // Per Windows ABI, ctored by caller, dtored by callee
121 int i
= bar(foo(0), B1(), B2());
123 // Test: returned by value
124 // Per Windows ABI, caller allocate a temp in stack, then ctored by callee,
125 // finally dtored in caller after consumed
126 class B1 b1fromgoo
= goo(i
);
128 return m
+ b1fromgoo
.data
+ b3inmain
.data
;