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