1 // RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s 2 // RUN: %clang_cc1 -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: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 104 // CHECK-EH-NEXT: catch i8* null 105 // CHECK-EH-NEXT: call void @_ZSt9terminatev() 106 // CHECK-EH-NEXT: unreachable 107 108 } 109 110 X test3(bool B) { 111 // FIXME: We don't manage to apply NRVO here, although we could. 112 { 113 X y; 114 return y; 115 } 116 X x; 117 return x; 118 } 119 120 extern "C" void exit(int) throw(); 121 122 // CHECK: define void @_Z5test4b 123 X test4(bool B) { 124 { 125 // CHECK: tail call {{.*}} @_ZN1XC1Ev 126 X x; 127 // CHECK: br i1 128 if (B) 129 return x; 130 } 131 // CHECK: tail call {{.*}} @_ZN1XD1Ev 132 // CHECK: tail call void @exit(i32 1) 133 exit(1); 134 } 135 136 #ifdef __EXCEPTIONS 137 // CHECK-EH: define void @_Z5test5 138 void may_throw(); 139 X test5() { 140 try { 141 may_throw(); 142 } catch (X x) { 143 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_ 144 // CHECK-EH: call void @__cxa_end_catch() 145 // CHECK-EH: ret void 146 return x; 147 } 148 } 149 #endif 150 151 // rdar://problem/10430868 152 // CHECK: define void @_Z5test6v 153 X test6() { 154 X a __attribute__((aligned(8))); 155 return a; 156 // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 157 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) 158 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]]) 159 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) 160 // CHECK-NEXT: ret void 161 } 162