1 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 %s 2 // RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-LIFETIME %s 3 4 struct A { 5 A(); 6 ~A(); 7 int a; 8 }; 9 10 A getA(); 11 12 int TakesTwo(A a, A b); 13 void HasEHCleanup() { 14 TakesTwo(getA(), getA()); 15 } 16 17 // With exceptions, we need to clean up at least one of these temporaries. 18 // WIN32-LABEL: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} { 19 // WIN32: %[[base:.*]] = call i8* @llvm.stacksave() 20 // If this call throws, we have to restore the stack. 21 // WIN32: call void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 22 // If this call throws, we have to cleanup the first temporary. 23 // WIN32: invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 24 // If this call throws, we have to cleanup the stacksave. 25 // WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 26 // WIN32: call void @llvm.stackrestore 27 // WIN32: ret void 28 // 29 // There should be one dtor call for unwinding from the second getA. 30 // WIN32: cleanuppad 31 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 32 // WIN32-NOT: @"\01??1A@@QAE@XZ" 33 // WIN32: } 34 35 void TakeRef(const A &a); 36 int HasDeactivatedCleanups() { 37 return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())); 38 } 39 40 // WIN32-LABEL: define i32 @"\01?HasDeactivatedCleanups@@YAHXZ"() {{.*}} { 41 // WIN32: %[[isactive:.*]] = alloca i1 42 // WIN32: call i8* @llvm.stacksave() 43 // WIN32: %[[argmem:.*]] = alloca inalloca [[argmem_ty:<{ %struct.A, %struct.A }>]] 44 // WIN32: %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1 45 // WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 46 // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 47 // 48 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]]) 49 // WIN32: store i1 true, i1* %[[isactive]] 50 // 51 // WIN32: %[[arg0:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 52 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 53 // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 54 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 55 // WIN32: store i1 false, i1* %[[isactive]] 56 // 57 // WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]]) 58 // Destroy the two const ref temporaries. 59 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 60 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 61 // WIN32: ret i32 62 // 63 // Conditionally destroy arg1. 64 // WIN32: %[[cond:.*]] = load i1, i1* %[[isactive]] 65 // WIN32: br i1 %[[cond]] 66 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 67 // WIN32: } 68 69 // Test putting the cleanups inside a conditional. 70 int CouldThrow(); 71 int HasConditionalCleanup(bool cond) { 72 return (cond ? TakesTwo(A(), A()) : CouldThrow()); 73 } 74 75 // WIN32-LABEL: define i32 @"\01?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} { 76 // WIN32: store i1 false 77 // WIN32: br i1 78 // WIN32: call i8* @llvm.stacksave() 79 // WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) 80 // WIN32: store i1 true 81 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) 82 // WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 83 // 84 // WIN32: call void @llvm.stackrestore 85 // 86 // WIN32: call i32 @"\01?CouldThrow@@YAHXZ"() 87 // 88 // Only one dtor in the invoke for arg1 89 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 90 // WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 91 // WIN32: } 92 93 // Now test both. 94 int HasConditionalDeactivatedCleanups(bool cond) { 95 return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow()); 96 } 97 98 // WIN32-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} { 99 // WIN32: alloca i1 100 // WIN32: %[[arg1_cond:.*]] = alloca i1 101 // Start all four cleanups as deactivated. 102 // WIN32: store i1 false 103 // WIN32: store i1 false 104 // WIN32: store i1 false 105 // WIN32: store i1 false 106 // WIN32: br i1 107 // True condition. 108 // WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 109 // WIN32: store i1 true 110 // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 111 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 112 // WIN32: store i1 true, i1* %[[arg1_cond]] 113 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 114 // WIN32: store i1 true 115 // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 116 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 117 // WIN32: store i1 true 118 // WIN32: store i1 false, i1* %[[arg1_cond]] 119 // WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 120 // False condition. 121 // WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"() 122 // Two normal cleanups for TakeRef args. 123 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 124 // WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 125 // WIN32: ret i32 126 // 127 // Somewhere in the landing pad soup, we conditionally destroy arg1. 128 // WIN32: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]] 129 // WIN32: br i1 %[[isactive]] 130 // WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 131 // WIN32: } 132 133 namespace crash_on_partial_destroy { 134 struct A { 135 virtual ~A(); 136 }; 137 138 struct B : virtual A { 139 // Has an implicit destructor. 140 }; 141 142 struct C : B { 143 C(); 144 }; 145 146 void foo(); 147 // We used to crash when emitting this. 148 C::C() { foo(); } 149 150 // Verify that we don't bother with a vbtable lookup when adjusting the this 151 // pointer to call a base destructor from a constructor while unwinding. 152 // WIN32-LABEL: define {{.*}} @"\01??0C@crash_on_partial_destroy@@QAE@XZ"{{.*}} { 153 // WIN32: cleanuppad 154 // 155 // We shouldn't do any vbptr loads, just constant GEPs. 156 // WIN32-NOT: load 157 // WIN32: getelementptr i8, i8* %{{.*}}, i32 4 158 // WIN32-NOT: load 159 // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::B"* 160 // WIN32: call x86_thiscallcc void @"\01??1B@crash_on_partial_destroy@@UAE@XZ" 161 // 162 // WIN32-NOT: load 163 // WIN32: bitcast %"struct.crash_on_partial_destroy::C"* %{{.*}} to i8* 164 // WIN32-NOT: load 165 // WIN32: getelementptr inbounds i8, i8* %{{.*}}, i32 4 166 // WIN32-NOT: load 167 // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"* 168 // WIN32: call x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ"({{.*}}) 169 // WIN32: } 170 } 171 172 namespace dont_call_terminate { 173 struct C { 174 ~C(); 175 }; 176 void g(); 177 void f() { 178 C c; 179 g(); 180 } 181 182 // WIN32-LABEL: define void @"\01?f@dont_call_terminate@@YAXXZ"() 183 // WIN32: invoke void @"\01?g@dont_call_terminate@@YAXXZ"() 184 // WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 185 // 186 // WIN32: [[cont]] 187 // WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) 188 // 189 // WIN32: [[lpad]] 190 // WIN32-NEXT: cleanuppad 191 // WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) 192 } 193 194 namespace noexcept_false_dtor { 195 struct D { 196 ~D() noexcept(false); 197 }; 198 void f() { 199 D d; 200 CouldThrow(); 201 } 202 } 203 204 // WIN32-LABEL: define void @"\01?f@noexcept_false_dtor@@YAXXZ"() 205 // WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"() 206 // WIN32: call x86_thiscallcc void @"\01??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}}) 207 // WIN32: cleanuppad 208 // WIN32: call x86_thiscallcc void @"\01??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}}) 209 // WIN32: cleanupret 210 211 namespace lifetime_marker { 212 struct C { 213 ~C(); 214 }; 215 void g(); 216 void f() { 217 C c; 218 g(); 219 } 220 221 // WIN32-LIFETIME-LABEL: define void @"\01?f@lifetime_marker@@YAXXZ"() 222 // WIN32-LIFETIME: %[[c:.*]] = alloca %"struct.lifetime_marker::C" 223 // WIN32-LIFETIME: %[[bc0:.*]] = bitcast %"struct.lifetime_marker::C"* %c to i8* 224 // WIN32-LIFETIME: call void @llvm.lifetime.start(i64 1, i8* %[[bc0]]) 225 // WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"() 226 // WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]] 227 // 228 // WIN32-LIFETIME: [[cont]] 229 // WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) 230 // WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* 231 // WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc1]]) 232 // 233 // WIN32-LIFETIME: [[lpad0]] 234 // WIN32-LIFETIME-NEXT: cleanuppad 235 // WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) 236 // WIN32-LIFETIME: cleanupret {{.*}} unwind label %[[lpad1:[^ ]*]] 237 // 238 // WIN32-LIFETIME: [[lpad1]] 239 // WIN32-LIFETIME-NEXT: cleanuppad 240 // WIN32-LIFETIME: %[[bc2:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* 241 // WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc2]]) 242 } 243