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();
15   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
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(
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*)
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-03-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
89   // CHECK-EH-03-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
90   // CHECK-EH-NEXT: br label
91   // -> %eh.cleanup
92 
93   // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
94   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
95   // -> %eh.cleanup, %terminate.lpad
96   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
97 
98   // %if.end: returning 'y'
99   // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
100   // -> %cleanup, %lpad1
101 
102   // %cleanup: normal cleanup for 'y'
103   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
104   // -> %invoke.cont11, %lpad
105   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
106 
107   // %invoke.cont11: normal cleanup for 'x'
108   // CHECK-EH:      call void @llvm.lifetime.end
109   // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev
110   // CHECK-EH-NEXT: call void @llvm.lifetime.end
111   // CHECK-EH-NEXT: ret void
112 
113   // %eh.cleanup:  EH cleanup for 'x'
114   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
115   // -> %invoke.cont17, %terminate.lpad
116   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
117 
118   // %invoke.cont17: rethrow block for %eh.cleanup.
119   // This really should be elsewhere in the function.
120   // CHECK-EH:      resume { i8*, i32 }
121 
122   // %terminate.lpad: terminate landing pad.
123   // CHECK-EH-03:      [[T0:%.*]] = landingpad { i8*, i32 }
124   // CHECK-EH-03-NEXT:   catch i8* null
125   // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
126   // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
127   // CHECK-EH-03-NEXT: unreachable
128 
129 }
130 
131 // CHECK-LABEL: define void @_Z5test3b
132 X test3(bool B) {
133   // CHECK: call {{.*}} @_ZN1XC1Ev
134   // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
135   // CHECK: call {{.*}} @_ZN1XC1Ev
136   // CHECK: call {{.*}} @_ZN1XC1ERKS_
137   if (B) {
138     X y;
139     return y;
140   }
141   // FIXME: we should NRVO this variable too.
142   X x;
143   return x;
144 }
145 
146 extern "C" void exit(int) throw();
147 
148 // CHECK-LABEL: define void @_Z5test4b
149 X test4(bool B) {
150   {
151     // CHECK: call {{.*}} @_ZN1XC1Ev
152     X x;
153     // CHECK: br i1
154     if (B)
155       return x;
156   }
157   // CHECK: call {{.*}} @_ZN1XD1Ev
158   // CHECK: call void @exit(i32 1)
159   exit(1);
160 }
161 
162 #ifdef __EXCEPTIONS
163 // CHECK-EH-LABEL: define void @_Z5test5
164 void may_throw();
165 X test5() {
166   try {
167     may_throw();
168   } catch (X x) {
169     // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
170     // CHECK-EH: call void @__cxa_end_catch()
171     // CHECK-EH: ret void
172     return x;
173   }
174 }
175 #endif
176 
177 // rdar://problem/10430868
178 // CHECK-LABEL: define void @_Z5test6v
179 X test6() {
180   X a __attribute__((aligned(8)));
181   return a;
182   // CHECK:      [[A:%.*]] = alloca [[X:%.*]], align 8
183   // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0
184   // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[PTR]])
185   // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]])
186   // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[A]])
187   // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]])
188   // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[PTR]])
189   // CHECK-NEXT: ret void
190 }
191 
192 // CHECK-LABEL: define void @_Z5test7b
193 X test7(bool b) {
194   // CHECK: call {{.*}} @_ZN1XC1Ev
195   // CHECK-NEXT: ret
196   if (b) {
197     X x;
198     return x;
199   }
200   return X();
201 }
202 
203 // CHECK-LABEL: define void @_Z5test8b
204 X test8(bool b) {
205   // CHECK: call {{.*}} @_ZN1XC1Ev
206   // CHECK-NEXT: ret
207   if (b) {
208     X x;
209     return x;
210   } else {
211     X y;
212     return y;
213   }
214 }
215 
216 Y<int> test9() {
217   Y<int>::f();
218 }
219 
220 // CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
221 // CHECK: call {{.*}} @_ZN1YIiEC1Ev
222 
223 // CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
224