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 -check-prefix WIN32-O0 %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-O3 -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-O0-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} { 99 // WIN32-O0: alloca i1 100 // WIN32-O0: %[[arg1_cond:.*]] = alloca i1 101 // Start all four cleanups as deactivated. 102 // WIN32-O0: store i1 false 103 // WIN32-O0: store i1 false 104 // WIN32-O0: store i1 false 105 // WIN32-O0: store i1 false 106 // WIN32-O0: br i1 107 // True condition. 108 // WIN32-O0: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 109 // WIN32-O0: store i1 true 110 // WIN32-O0: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 111 // WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 112 // WIN32-O0: store i1 true, i1* %[[arg1_cond]] 113 // WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 114 // WIN32-O0: store i1 true 115 // WIN32-O0: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 116 // WIN32-O0: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 117 // WIN32-O0: store i1 true 118 // WIN32-O0: store i1 false, i1* %[[arg1_cond]] 119 // WIN32-O0: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 120 // False condition. 121 // WIN32-O0: invoke i32 @"\01?CouldThrow@@YAHXZ"() 122 // Two normal cleanups for TakeRef args. 123 // WIN32-O0: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 124 // WIN32-O0-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 125 // WIN32-O0: ret i32 126 // 127 // Somewhere in the landing pad soup, we conditionally destroy arg1. 128 // WIN32-O0: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]] 129 // WIN32-O0: br i1 %[[isactive]] 130 // WIN32-O0: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 131 // WIN32-O0: } 132 133 // WIN32-O3-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} { 134 // WIN32-O3: alloca i1 135 // WIN32-O3: alloca i1 136 // WIN32-O3: %[[arg1_cond:.*]] = alloca i1 137 // Start all four cleanups as deactivated. 138 // WIN32-O3: store i1 false 139 // WIN32-O3: store i1 false 140 // WIN32-O3: store i1 false 141 // WIN32-O3: store i1 false 142 // WIN32-O3: store i1 false 143 // WIN32-O3: store i1 false 144 // WIN32-O3: br i1 145 // True condition. 146 // WIN32-O3: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 147 // WIN32-O3: store i1 true 148 // WIN32-O3: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 149 // WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 150 // WIN32-O3: store i1 true, i1* %[[arg1_cond]] 151 // WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 152 // WIN32-O3: store i1 true 153 // WIN32-O3: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 154 // WIN32-O3: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 155 // WIN32-O3: store i1 true 156 // WIN32-O3: store i1 false, i1* %[[arg1_cond]] 157 // WIN32-O3: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 158 // False condition. 159 // WIN32-O3: invoke i32 @"\01?CouldThrow@@YAHXZ"() 160 // Two normal cleanups for TakeRef args. 161 // WIN32-O3: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 162 // WIN32-O3-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 163 // WIN32-O3: ret i32 164 // 165 // Somewhere in the landing pad soup, we conditionally destroy arg1. 166 // WIN32-O3: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]] 167 // WIN32-O3: br i1 %[[isactive]] 168 // WIN32-O3: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) 169 // WIN32-O3: } 170 171 namespace crash_on_partial_destroy { 172 struct A { 173 virtual ~A(); 174 }; 175 176 struct B : virtual A { 177 // Has an implicit destructor. 178 }; 179 180 struct C : B { 181 C(); 182 }; 183 184 void foo(); 185 // We used to crash when emitting this. 186 C::C() { foo(); } 187 188 // Verify that we don't bother with a vbtable lookup when adjusting the this 189 // pointer to call a base destructor from a constructor while unwinding. 190 // WIN32-LABEL: define {{.*}} @"\01??0C@crash_on_partial_destroy@@QAE@XZ"{{.*}} { 191 // WIN32: cleanuppad 192 // 193 // We shouldn't do any vbptr loads, just constant GEPs. 194 // WIN32-NOT: load 195 // WIN32: getelementptr i8, i8* %{{.*}}, i32 4 196 // WIN32-NOT: load 197 // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::B"* 198 // WIN32: call x86_thiscallcc void @"\01??1B@crash_on_partial_destroy@@UAE@XZ" 199 // 200 // WIN32-NOT: load 201 // WIN32: bitcast %"struct.crash_on_partial_destroy::C"* %{{.*}} to i8* 202 // WIN32-NOT: load 203 // WIN32: getelementptr inbounds i8, i8* %{{.*}}, i32 4 204 // WIN32-NOT: load 205 // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"* 206 // WIN32: call x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ"({{.*}}) 207 // WIN32: } 208 } 209 210 namespace dont_call_terminate { 211 struct C { 212 ~C(); 213 }; 214 void g(); 215 void f() { 216 C c; 217 g(); 218 } 219 220 // WIN32-LABEL: define void @"\01?f@dont_call_terminate@@YAXXZ"() 221 // WIN32: invoke void @"\01?g@dont_call_terminate@@YAXXZ"() 222 // WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 223 // 224 // WIN32: [[cont]] 225 // WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) 226 // 227 // WIN32: [[lpad]] 228 // WIN32-NEXT: cleanuppad 229 // WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) 230 } 231 232 namespace noexcept_false_dtor { 233 struct D { 234 ~D() noexcept(false); 235 }; 236 void f() { 237 D d; 238 CouldThrow(); 239 } 240 } 241 242 // WIN32-LABEL: define void @"\01?f@noexcept_false_dtor@@YAXXZ"() 243 // WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"() 244 // WIN32: call x86_thiscallcc void @"\01??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}}) 245 // WIN32: cleanuppad 246 // WIN32: call x86_thiscallcc void @"\01??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}}) 247 // WIN32: cleanupret 248 249 namespace lifetime_marker { 250 struct C { 251 ~C(); 252 }; 253 void g(); 254 void f() { 255 C c; 256 g(); 257 } 258 259 // WIN32-LIFETIME-LABEL: define void @"\01?f@lifetime_marker@@YAXXZ"() 260 // WIN32-LIFETIME: %[[c:.*]] = alloca %"struct.lifetime_marker::C" 261 // WIN32-LIFETIME: %[[bc0:.*]] = bitcast %"struct.lifetime_marker::C"* %c to i8* 262 // WIN32-LIFETIME: call void @llvm.lifetime.start(i64 1, i8* %[[bc0]]) 263 // WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"() 264 // WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]] 265 // 266 // WIN32-LIFETIME: [[cont]] 267 // WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) 268 // WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* 269 // WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc1]]) 270 // 271 // WIN32-LIFETIME: [[lpad0]] 272 // WIN32-LIFETIME-NEXT: cleanuppad 273 // WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) 274 // WIN32-LIFETIME: cleanupret {{.*}} unwind label %[[lpad1:[^ ]*]] 275 // 276 // WIN32-LIFETIME: [[lpad1]] 277 // WIN32-LIFETIME-NEXT: cleanuppad 278 // WIN32-LIFETIME: %[[bc2:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* 279 // WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc2]]) 280 } 281