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