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