1 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -o - %s | FileCheck %s
2 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
3 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
4
5 // Test code generation for the named return value optimization.
6 class X {
7 public:
8 X();
9 X(const X&);
10 ~X();
11 };
12
13 template<typename T> struct Y {
14 Y();
fY15 static Y f() {
16 Y y;
17 return y;
18 }
19 };
20
21 // CHECK-LABEL: define void @_Z5test0v
22 // CHECK-EH-LABEL: define void @_Z5test0v
test0()23 X test0() {
24 X x;
25 // CHECK: call {{.*}} @_ZN1XC1Ev
26 // CHECK-NEXT: ret void
27
28 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
29 // CHECK-EH-NEXT: ret void
30 return x;
31 }
32
33 // CHECK-LABEL: define void @_Z5test1b(
34 // CHECK-EH-LABEL: define void @_Z5test1b(
test1(bool B)35 X test1(bool B) {
36 // CHECK: call {{.*}} @_ZN1XC1Ev
37 // CHECK-NEXT: ret void
38 X x;
39 if (B)
40 return (x);
41 return x;
42 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
43 // CHECK-EH-NEXT: ret void
44 }
45
46 // CHECK-LABEL: define void @_Z5test2b
47 // CHECK-EH-LABEL: define void @_Z5test2b
48 // CHECK-EH-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
test2(bool B)49 X test2(bool B) {
50 // No NRVO.
51
52 X x;
53 X y;
54 if (B)
55 return y;
56 return x;
57
58 // CHECK: call {{.*}} @_ZN1XC1Ev
59 // CHECK-NEXT: {{.*}} getelementptr inbounds %class.X, %class.X* %y, i32 0, i32 0
60 // CHECK-NEXT: call void @llvm.lifetime.start
61 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
62 // CHECK: call {{.*}} @_ZN1XC1ERKS_
63 // CHECK: call {{.*}} @_ZN1XD1Ev
64 // CHECK-NEXT: call void @llvm.lifetime.end
65 // CHECK: call {{.*}} @_ZN1XD1Ev
66 // CHECK-NEXT: call void @llvm.lifetime.end
67 // CHECK: ret void
68
69 // The block ordering in the -fexceptions IR is unfortunate.
70
71 // CHECK-EH: call void @llvm.lifetime.start
72 // CHECK-EH-NEXT: call {{.*}} @_ZN1XC1Ev
73 // CHECK-EH: call void @llvm.lifetime.start
74 // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
75 // -> %invoke.cont, %lpad
76
77 // %invoke.cont:
78 // CHECK-EH: br i1
79 // -> %if.then, %if.end
80
81 // %if.then: returning 'x'
82 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
83 // -> %cleanup, %lpad1
84
85 // %lpad: landing pad for ctor of 'y', dtor of 'y'
86 // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 }
87 // CHECK-EH-NEXT: cleanup
88 // CHECK-EH-NEXT: br label
89 // -> %eh.cleanup
90
91 // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
92 // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
93 // -> %eh.cleanup, %terminate.lpad
94 // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
95
96 // %if.end: returning 'y'
97 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
98 // -> %cleanup, %lpad1
99
100 // %cleanup: normal cleanup for 'y'
101 // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
102 // -> %invoke.cont11, %lpad
103 // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
104
105 // %invoke.cont11: normal cleanup for 'x'
106 // CHECK-EH: call void @llvm.lifetime.end
107 // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev
108 // CHECK-EH-NEXT: call void @llvm.lifetime.end
109 // CHECK-EH-NEXT: ret void
110
111 // %eh.cleanup: EH cleanup for 'x'
112 // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
113 // -> %invoke.cont17, %terminate.lpad
114 // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
115
116 // %invoke.cont17: rethrow block for %eh.cleanup.
117 // This really should be elsewhere in the function.
118 // CHECK-EH: resume { i8*, i32 }
119
120 // %terminate.lpad: terminate landing pad.
121 // CHECK-EH-03: [[T0:%.*]] = landingpad { i8*, i32 }
122 // CHECK-EH-03-NEXT: catch i8* null
123 // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
124 // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
125 // CHECK-EH-03-NEXT: unreachable
126
127 }
128
129 // CHECK-LABEL: define void @_Z5test3b
test3(bool B)130 X test3(bool B) {
131 // CHECK: call {{.*}} @_ZN1XC1Ev
132 // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
133 // CHECK: call {{.*}} @_ZN1XC1Ev
134 // CHECK: call {{.*}} @_ZN1XC1ERKS_
135 if (B) {
136 X y;
137 return y;
138 }
139 // FIXME: we should NRVO this variable too.
140 X x;
141 return x;
142 }
143
144 extern "C" void exit(int) throw();
145
146 // CHECK-LABEL: define void @_Z5test4b
test4(bool B)147 X test4(bool B) {
148 {
149 // CHECK: call {{.*}} @_ZN1XC1Ev
150 X x;
151 // CHECK: br i1
152 if (B)
153 return x;
154 }
155 // CHECK: call {{.*}} @_ZN1XD1Ev
156 // CHECK: call void @exit(i32 1)
157 exit(1);
158 }
159
160 #ifdef __EXCEPTIONS
161 // CHECK-EH-LABEL: define void @_Z5test5
162 void may_throw();
test5()163 X test5() {
164 try {
165 may_throw();
166 } catch (X x) {
167 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
168 // CHECK-EH: call void @__cxa_end_catch()
169 // CHECK-EH: ret void
170 return x;
171 }
172 }
173 #endif
174
175 // rdar://problem/10430868
176 // CHECK-LABEL: define void @_Z5test6v
test6()177 X test6() {
178 X a __attribute__((aligned(8)));
179 return a;
180 // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
181 // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0
182 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[PTR]])
183 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]])
184 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[A]])
185 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]])
186 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[PTR]])
187 // CHECK-NEXT: ret void
188 }
189
190 // CHECK-LABEL: define void @_Z5test7b
test7(bool b)191 X test7(bool b) {
192 // CHECK: call {{.*}} @_ZN1XC1Ev
193 // CHECK-NEXT: ret
194 if (b) {
195 X x;
196 return x;
197 }
198 return X();
199 }
200
201 // CHECK-LABEL: define void @_Z5test8b
test8(bool b)202 X test8(bool b) {
203 // CHECK: call {{.*}} @_ZN1XC1Ev
204 // CHECK-NEXT: ret
205 if (b) {
206 X x;
207 return x;
208 } else {
209 X y;
210 return y;
211 }
212 }
213
test9()214 Y<int> test9() {
215 Y<int>::f();
216 }
217
218 // CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
219 // CHECK: call {{.*}} @_ZN1YIiEC1Ev
220
221 // CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
222