Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s
      2 // RUN: %clang_cc1 %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s
      3 
      4 struct A {
      5   A();
      6 #ifdef WITH_DTOR
      7   ~A();
      8 #endif
      9   char a[1024];
     10   operator bool() const;
     11 };
     12 
     13 template <typename T>
     14 void Foo(T &&);
     15 
     16 template <typename T>
     17 void Bar(T &&);
     18 
     19 template <typename T>
     20 T Baz();
     21 
     22 void Test1() {
     23   // CHECK-DTOR-LABEL: Test1
     24   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
     25   // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
     26   // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
     27   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
     28   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
     29   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
     30   // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
     31   // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
     32   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
     33   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
     34   // CHECK-DTOR: }
     35 
     36   // CHECK-NO-DTOR-LABEL: Test1
     37   // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
     38   // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
     39   // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
     40   // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
     41   // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
     42   // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
     43   // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
     44   // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
     45   // CHECK-NO-DTOR: }
     46   {
     47     const A &a = A{};
     48     Foo(a);
     49   }
     50   {
     51     const A &a = A{};
     52     Foo(a);
     53   }
     54 }
     55 
     56 void Test2() {
     57   // CHECK-DTOR-LABEL: Test2
     58   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]])
     59   // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
     60   // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
     61   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]])
     62   // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
     63   // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
     64   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR2]])
     65   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]])
     66   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR1]])
     67   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]])
     68   // CHECK-DTOR: }
     69 
     70   // CHECK-NO-DTOR-LABEL: Test2
     71   // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]])
     72   // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
     73   // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
     74   // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]])
     75   // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
     76   // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
     77   // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]])
     78   // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]])
     79   // CHECK-NO-DTOR: }
     80   const A &a = A{};
     81   Foo(a);
     82   const A &b = A{};
     83   Foo(b);
     84 }
     85 
     86 void Test3() {
     87   // CHECK-DTOR-LABEL: Test3
     88   // CHECK-DTOR: call void @llvm.lifetime.start
     89   // CHECK-DTOR: call void @llvm.lifetime.start
     90 
     91   // if.then:
     92   // CHECK-DTOR: call void @llvm.lifetime.end
     93 
     94   // cleanup:
     95   // CHECK-DTOR: call void @llvm.lifetime.end
     96 
     97   // cleanup:
     98   // CHECK-DTOR: call void @llvm.lifetime.end
     99   // CHECK-DTOR: }
    100   const A &a = A{};
    101   if (const A &b = A(a)) {
    102     Foo(b);
    103     return;
    104   }
    105   Bar(a);
    106 }
    107 
    108 void Test4() {
    109   // CHECK-DTOR-LABEL: Test4
    110   // CHECK-DTOR: call void @llvm.lifetime.start
    111 
    112   // for.cond.cleanup:
    113   // CHECK-DTOR: call void @llvm.lifetime.end
    114 
    115   // for.body:
    116   // CHECK-DTOR: }
    117   for (const A &a = A{}; a;) {
    118     Foo(a);
    119   }
    120 }
    121 
    122 int Test5() {
    123   // CHECK-DTOR-LABEL: Test5
    124   // CHECK-DTOR: call void @llvm.lifetime.start
    125   // CHECK-DTOR: call i32 @_Z3BazIiET_v()
    126   // CHECK-DTOR: store
    127   // CHECK-DTOR: call void @_Z3FooIRKiEvOT_
    128   // CHECK-DTOR: load
    129   // CHECK-DTOR: call void @llvm.lifetime.end
    130   // CHECK-DTOR: }
    131   const int &a = Baz<int>();
    132   Foo(a);
    133   return a;
    134 }
    135 
    136 void Test6() {
    137   // CHECK-DTOR-LABEL: Test6
    138   // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
    139   // CHECK-DTOR: call i32 @_Z3BazIiET_v()
    140   // CHECK-DTOR: store
    141   // CHECK-DTOR: call void @_Z3FooIiEvOT_
    142   // CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]])
    143   // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
    144   // CHECK-DTOR: call i32 @_Z3BazIiET_v()
    145   // CHECK-DTOR: store
    146   // CHECK-DTOR: call void @_Z3FooIiEvOT_
    147   // CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]])
    148   // CHECK-DTOR: }
    149   Foo(Baz<int>());
    150   Foo(Baz<int>());
    151 }
    152 
    153 void Test7() {
    154   // CHECK-DTOR-LABEL: Test7
    155   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
    156   // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
    157   // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
    158   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]])
    159   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
    160   // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
    161   // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
    162   // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
    163   // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]])
    164   // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
    165   // CHECK-DTOR: }
    166   Foo(Baz<A>());
    167   Foo(Baz<A>());
    168 }
    169