Home | History | Annotate | Download | only in CodeGenCXX
      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