Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -disable-llvm-optzns -O2 -emit-llvm -o %t.ll
      2 // RUN: FileCheck --check-prefix=CHECK-CTORS %s < %t.ll
      3 // RUN: FileCheck --check-prefix=CHECK-NEW %s < %t.ll
      4 // RUN: FileCheck --check-prefix=CHECK-DTORS %s < %t.ll
      5 // RUN: FileCheck --check-prefix=CHECK-LINK-REQ %s < %t.ll
      6 
      7 typedef __typeof__(sizeof(0)) size_t;
      8 void *operator new(size_t, void*) throw();
      9 
     10 struct NotTrivialDtor {
     11   ~NotTrivialDtor();
     12 };
     13 
     14 struct DynamicBase1 {
     15   NotTrivialDtor obj;
     16   virtual void foo();
     17 };
     18 
     19 struct DynamicDerived : DynamicBase1 {
     20   void foo();
     21 };
     22 
     23 struct DynamicBase2 {
     24   virtual void bar();
     25   ~DynamicBase2() {
     26     bar();
     27   }
     28 };
     29 
     30 struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 {
     31   virtual void foo();
     32   virtual void bar();
     33 };
     34 
     35 struct StaticBase {
     36   NotTrivialDtor obj;
     37   void bar();
     38 };
     39 
     40 struct DynamicFromStatic : StaticBase {
     41   virtual void bar();
     42 };
     43 
     44 struct DynamicFromVirtualStatic1 : virtual StaticBase {
     45 };
     46 
     47 struct DynamicFromVirtualStatic2 : virtual StaticBase {
     48 };
     49 
     50 struct DynamicFrom2Virtuals :
     51             DynamicFromVirtualStatic1,
     52             DynamicFromVirtualStatic2 {
     53 };
     54 
     55 // CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
     56 // CHECK-NEW-NOT: @llvm.invariant.group.barrier(
     57 // CHECK-NEW-LABEL: }
     58 void LocalObjects() {
     59   DynamicBase1 DB;
     60   DB.foo();
     61   DynamicDerived DD;
     62   DD.foo();
     63 
     64   DynamicBase2 DB2;
     65   DB2.bar();
     66 
     67   StaticBase SB;
     68   SB.bar();
     69 
     70   DynamicDerivedMultiple DDM;
     71   DDM.foo();
     72   DDM.bar();
     73 
     74   DynamicFromStatic DFS;
     75   DFS.bar();
     76   DynamicFromVirtualStatic1 DFVS1;
     77   DFVS1.bar();
     78   DynamicFrom2Virtuals DF2V;
     79   DF2V.bar();
     80 }
     81 
     82 struct DynamicFromVirtualStatic1;
     83 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
     84 // CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
     85 // CHECK-CTORS-LABEL: }
     86 
     87 struct DynamicFrom2Virtuals;
     88 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
     89 // CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
     90 // CHECK-CTORS-LABEL: }
     91 
     92 
     93 // CHECK-NEW-LABEL: define void @_Z9Pointers1v()
     94 // CHECK-NEW-NOT: @llvm.invariant.group.barrier(
     95 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
     96 
     97 // CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS2:.*]])
     98 // CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
     99 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
    100 // CHECK-NEW-LABEL: }
    101 void Pointers1() {
    102   DynamicBase1 *DB = new DynamicBase1;
    103   DB->foo();
    104 
    105   DynamicDerived *DD = new (DB) DynamicDerived;
    106   DD->foo();
    107   DD->~DynamicDerived();
    108 }
    109 
    110 // CHECK-NEW-LABEL: define void @_Z14HackingObjectsv()
    111 // CHECK-NEW:  call void @_ZN12DynamicBase1C1Ev
    112 // CHECK-NEW:  call i8* @llvm.invariant.group.barrier(
    113 // CHECK-NEW:  call void @_ZN14DynamicDerivedC1Ev(
    114 // CHECK-NEW:  call i8* @llvm.invariant.group.barrier(
    115 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
    116 // CHECK-NEW-LABEL: }
    117 void HackingObjects() {
    118   DynamicBase1 DB;
    119   DB.foo();
    120 
    121   DynamicDerived *DB2 = new (&DB) DynamicDerived;
    122   // Using DB now is prohibited.
    123   DB2->foo();
    124   DB2->~DynamicDerived();
    125 
    126   // We have to get back to the previous type to avoid calling wrong destructor
    127   new (&DB) DynamicBase1;
    128   DB.foo();
    129 }
    130 
    131 /*** Testing Constructors ***/
    132 struct DynamicBase1;
    133 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
    134 // CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier(
    135 // CHECK-CTORS-LABEL: }
    136 
    137 
    138 struct DynamicDerived;
    139 
    140 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
    141 // CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
    142 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
    143 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1:.*]])
    144 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
    145 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
    146 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]])
    147 
    148 // CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)***
    149 // CHECK-CTORS: store {{.*}} %[[THIS5]]
    150 // CHECK-CTORS-LABEL: }
    151 
    152 struct DynamicDerivedMultiple;
    153 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev(
    154 
    155 // CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
    156 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
    157 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1]])
    158 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
    159 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
    160 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]])
    161 
    162 // CHECK-CTORS: call i8* @llvm.invariant.group.barrier(
    163 
    164 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
    165 // CHECK-CTORS-NOT: @llvm.invariant.group.barrier
    166 
    167 
    168 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
    169 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 2) {{.*}} %[[THIS10]]
    170 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
    171 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
    172 // CHECK-CTORS: %[[THIS12:.*]]  = bitcast i8* %[[THIS_ADD]] to i32 (...)***
    173 
    174 
    175 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, i32 6) {{.*}} %[[THIS12]]
    176 // CHECK-CTORS-LABEL: }
    177 
    178 struct DynamicFromStatic;
    179 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
    180 // CHECK-CTORS-NOT: @llvm.invariant.group.barrier(
    181 // CHECK-CTORS-LABEL: }
    182 
    183 
    184 /** DTORS **/
    185 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
    186 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
    187 // CHECK-DTORS-LABEL: }
    188 
    189 
    190 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev(
    191 // CHECK-DTORS-NOT: invariant.barrier
    192 // CHECK-DTORS-LABEL: }
    193 
    194 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
    195 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
    196 // CHECK-DTORS-LABEL: }
    197 
    198 
    199 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
    200 
    201 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
    202 // CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
    203 // CHECK-DTORS-LABEL: }
    204 
    205 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
    206 // CHECK-DTORS: call i8* @llvm.invariant.group.barrier(
    207 // CHECK-DTORS-LABEL: }
    208 
    209 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
    210 // CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
    211 // CHECK-DTORS-LABEL: }
    212 
    213 
    214 // CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:.*]], ![[SEC:.*]]{{.*}}}
    215 
    216 // CHECK-LINK-REQ: ![[FIRST]] = !{i32 1, !"StrictVTablePointers", i32 1}
    217 // CHECK-LINK-REQ: ![[SEC]] = !{i32 3, !"StrictVTablePointersRequirement", ![[META:.*]]}
    218 // CHECK-LINK-REQ: ![[META]] = !{!"StrictVTablePointers", i32 1}
    219 
    220