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: 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-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 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 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 noundef 1) 157 exit(1); 158 } 159 160 #ifdef __EXCEPTIONS 161 // CHECK-EH-LABEL: define{{.*}} void @_Z5test5 162 void may_throw(); 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 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]]* {{[^,]*}} [[A]]) 184 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{[^,]*}} {{%.*}}, [[X]]* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[A]]) 185 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* {{[^,]*}} [[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 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 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 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