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 -o - %s | FileCheck --check-prefix=CHECK-EH %s 3 4 // Test code generation for the named return value optimization. 5 class X { 6 public: 7 X(); 8 X(const X&); 9 ~X(); 10 }; 11 12 // CHECK: define void @_Z5test0v 13 // CHECK-EH: define void @_Z5test0v 14 X test0() { 15 X x; 16 // CHECK: call {{.*}} @_ZN1XC1Ev 17 // CHECK-NEXT: ret void 18 19 // CHECK-EH: call {{.*}} @_ZN1XC1Ev 20 // CHECK-EH-NEXT: ret void 21 return x; 22 } 23 24 // CHECK: define void @_Z5test1b( 25 // CHECK-EH: define void @_Z5test1b( 26 X test1(bool B) { 27 // CHECK: tail call {{.*}} @_ZN1XC1Ev 28 // CHECK-NEXT: ret void 29 X x; 30 if (B) 31 return (x); 32 return x; 33 // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev 34 // CHECK-EH-NEXT: ret void 35 } 36 37 // CHECK: define void @_Z5test2b 38 // CHECK-EH: define void @_Z5test2b 39 X test2(bool B) { 40 // No NRVO. 41 42 X x; 43 X y; 44 if (B) 45 return y; 46 return x; 47 48 // CHECK: call {{.*}} @_ZN1XC1Ev 49 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev 50 // CHECK: call {{.*}} @_ZN1XC1ERKS_ 51 // CHECK: call {{.*}} @_ZN1XC1ERKS_ 52 // CHECK: call {{.*}} @_ZN1XD1Ev 53 // CHECK: call {{.*}} @_ZN1XD1Ev 54 // CHECK: ret void 55 56 // The block ordering in the -fexceptions IR is unfortunate. 57 58 // CHECK-EH: call {{.*}} @_ZN1XC1Ev 59 // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev 60 // -> %invoke.cont, %lpad 61 62 // %invoke.cont: 63 // CHECK-EH: br i1 64 // -> %if.then, %if.end 65 66 // %if.then: returning 'x' 67 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ 68 // -> %cleanup, %lpad1 69 70 // %lpad: landing pad for ctor of 'y', dtor of 'y' 71 // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 72 // CHECK-EH-NEXT: cleanup 73 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 74 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 75 // CHECK-EH-NEXT: br label 76 // -> %eh.cleanup 77 78 // %lpad1: landing pad for return copy ctors, EH cleanup for 'y' 79 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev 80 // -> %eh.cleanup, %terminate.lpad 81 82 // %if.end: returning 'y' 83 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ 84 // -> %cleanup, %lpad1 85 86 // %cleanup: normal cleanup for 'y' 87 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev 88 // -> %invoke.cont11, %lpad 89 90 // %invoke.cont11: normal cleanup for 'x' 91 // CHECK-EH: call {{.*}} @_ZN1XD1Ev 92 // CHECK-EH-NEXT: ret void 93 94 // %eh.cleanup: EH cleanup for 'x' 95 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev 96 // -> %invoke.cont17, %terminate.lpad 97 98 // %invoke.cont17: rethrow block for %eh.cleanup. 99 // This really should be elsewhere in the function. 100 // CHECK-EH: resume { i8*, i32 } 101 102 // %terminate.lpad: terminate landing pad. 103 // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 104 // CHECK-EH-NEXT: catch i8* null 105 // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0 106 // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]] 107 // CHECK-EH-NEXT: unreachable 108 109 } 110 111 X test3(bool B) { 112 // FIXME: We don't manage to apply NRVO here, although we could. 113 { 114 X y; 115 return y; 116 } 117 X x; 118 return x; 119 } 120 121 extern "C" void exit(int) throw(); 122 123 // CHECK: define void @_Z5test4b 124 X test4(bool B) { 125 { 126 // CHECK: tail call {{.*}} @_ZN1XC1Ev 127 X x; 128 // CHECK: br i1 129 if (B) 130 return x; 131 } 132 // CHECK: tail call {{.*}} @_ZN1XD1Ev 133 // CHECK: tail call void @exit(i32 1) 134 exit(1); 135 } 136 137 #ifdef __EXCEPTIONS 138 // CHECK-EH: define void @_Z5test5 139 void may_throw(); 140 X test5() { 141 try { 142 may_throw(); 143 } catch (X x) { 144 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ 145 // CHECK-EH: call void @__cxa_end_catch() 146 // CHECK-EH: ret void 147 return x; 148 } 149 } 150 #endif 151 152 // rdar://problem/10430868 153 // CHECK: define void @_Z5test6v 154 X test6() { 155 X a __attribute__((aligned(8))); 156 return a; 157 // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 158 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) 159 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]]) 160 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) 161 // CHECK-NEXT: ret void 162 } 163 164 // CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind } 165