1 // RUN: %clang_cc1 -no-opaque-pointers %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -std=c++11 -disable-llvm-passes -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 using uintptr_t = unsigned long long;
10 
11 struct NotTrivialDtor {
12   ~NotTrivialDtor();
13 };
14 
15 struct DynamicBase1 {
16   NotTrivialDtor obj;
17   virtual void foo();
18 };
19 
20 struct DynamicDerived : DynamicBase1 {
21   void foo() override;
22 };
23 
24 struct DynamicBase2 {
25   virtual void bar();
~DynamicBase2DynamicBase226   ~DynamicBase2() {
27     bar();
28   }
29 };
30 
31 struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 {
32   void foo() override;
33   void bar() override;
34 };
35 
36 struct StaticBase {
37   NotTrivialDtor obj;
38   void bar();
39 };
40 
41 struct DynamicFromStatic : StaticBase {
42   virtual void bar();
43 };
44 
45 struct DynamicFromVirtualStatic1 : virtual StaticBase {
46 };
47 
48 struct DynamicFromVirtualStatic2 : virtual StaticBase {
49 };
50 
51 struct DynamicFrom2Virtuals : DynamicFromVirtualStatic1,
52                               DynamicFromVirtualStatic2 {
53 };
54 
55 // CHECK-NEW-LABEL: define{{.*}} void @_Z12LocalObjectsv()
56 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
57 // CHECK-NEW-LABEL: {{^}}}
LocalObjects()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.launder.invariant.group.p0i8(
85 // CHECK-CTORS-LABEL: {{^}}}
86 
87 struct DynamicFrom2Virtuals;
88 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
89 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
90 // CHECK-CTORS-LABEL: {{^}}}
91 
92 // CHECK-NEW-LABEL: define{{.*}} void @_Z9Pointers1v()
93 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
94 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
95 
96 // CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS2:.*]])
97 // CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
98 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* {{[^,]*}} %[[THIS4]])
99 // CHECK-NEW-LABEL: {{^}}}
Pointers1()100 void Pointers1() {
101   DynamicBase1 *DB = new DynamicBase1;
102   DB->foo();
103 
104   DynamicDerived *DD = new (DB) DynamicDerived;
105   DD->foo();
106   DD->~DynamicDerived();
107 }
108 
109 // CHECK-NEW-LABEL: define{{.*}} void @_Z14HackingObjectsv()
110 // CHECK-NEW:  call void @_ZN12DynamicBase1C1Ev
111 // CHECK-NEW:  call i8* @llvm.launder.invariant.group.p0i8(
112 // CHECK-NEW:  call void @_ZN14DynamicDerivedC1Ev(
113 // CHECK-NEW:  call i8* @llvm.launder.invariant.group.p0i8(
114 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
115 // CHECK-NEW-LABEL: {{^}}}
HackingObjects()116 void HackingObjects() {
117   DynamicBase1 DB;
118   DB.foo();
119 
120   DynamicDerived *DB2 = new (&DB) DynamicDerived;
121   // Using DB now is prohibited.
122   DB2->foo();
123   DB2->~DynamicDerived();
124 
125   // We have to get back to the previous type to avoid calling wrong destructor
126   new (&DB) DynamicBase1;
127   DB.foo();
128 }
129 
130 /*** Testing Constructors ***/
131 struct DynamicBase1;
132 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
133 // CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
134 // CHECK-CTORS-LABEL: {{^}}}
135 
136 struct DynamicDerived;
137 
138 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
139 // CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
140 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
141 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1:.*]])
142 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
143 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
144 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* {{[^,]*}} %[[THIS4]])
145 
146 // CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)***
147 // CHECK-CTORS: store {{.*}} %[[THIS5]]
148 // CHECK-CTORS-LABEL: {{^}}}
149 
150 struct DynamicDerivedMultiple;
151 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev(
152 
153 // CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
154 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
155 // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1]])
156 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
157 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
158 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* {{[^,]*}} %[[THIS4]])
159 
160 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
161 
162 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
163 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8
164 
165 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
166 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]]
167 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
168 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
169 // CHECK-CTORS: %[[THIS12:.*]]  = bitcast i8* %[[THIS_ADD]] to i32 (...)***
170 
171 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
172 // CHECK-CTORS-LABEL: {{^}}}
173 
174 struct DynamicFromStatic;
175 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
176 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8(
177 // CHECK-CTORS-LABEL: {{^}}}
178 
179 struct A {
180   virtual void foo();
181   int m;
182 };
183 struct B : A {
184   void foo() override;
185 };
186 
187 union U {
188   A a;
189   B b;
190 };
191 
192 void changeToB(U *u);
193 void changeToA(U *u);
194 
g2(A * a)195 void g2(A *a) {
196   a->foo();
197 }
198 // We have to guard access to union fields with invariant.group, because
199 // it is very easy to skip the barrier with unions. In this example the inlined
200 // g2 will produce loads with the same !invariant.group metadata, and
201 // u->a and u->b would use the same pointer.
202 // CHECK-NEW-LABEL: define{{.*}} void @_Z14UnionsBarriersP1U
UnionsBarriers(U * u)203 void UnionsBarriers(U *u) {
204   // CHECK-NEW: call void @_Z9changeToBP1U(
205   changeToB(u);
206   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
207   // CHECK-NEW: call void @_Z2g2P1A(%struct.A*
208   g2(&u->b);
209   // CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
210   changeToA(u);
211   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
212   // call void @_Z2g2P1A(%struct.A* %a)
213   g2(&u->a);
214   // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
215 }
216 
217 struct HoldingVirtuals {
218   A a;
219 };
220 
221 struct Empty {};
222 struct AnotherEmpty {
223   Empty e;
224 };
225 union NoVptrs {
226   int a;
227   AnotherEmpty empty;
228 };
229 void take(AnotherEmpty &);
230 
231 // CHECK-NEW-LABEL: noBarriers
noBarriers(NoVptrs & noVptrs)232 void noBarriers(NoVptrs &noVptrs) {
233   // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
234   // CHECK-NEW: 42
235   noVptrs.a += 42;
236   // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
237   // CHECK-NEW: call void @_Z4takeR12AnotherEmpty(
238   take(noVptrs.empty);
239 }
240 
241 union U2 {
242   HoldingVirtuals h;
243   int z;
244 };
245 void take(HoldingVirtuals &);
246 
247 // CHECK-NEW-LABEL: define{{.*}} void @_Z15UnionsBarriers2R2U2
UnionsBarriers2(U2 & u)248 void UnionsBarriers2(U2 &u) {
249   // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
250   // CHECK-NEW: 42
251   u.z += 42;
252   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
253   // CHECK-NEW: call void @_Z4takeR15HoldingVirtuals(
254   take(u.h);
255 }
256 
257 struct VirtualInBase : HoldingVirtuals, Empty {
258 };
259 
260 struct VirtualInVBase : virtual Empty, virtual HoldingVirtuals {
261 };
262 
263 // It has vtable by virtual inheritance.
264 struct VirtualInheritance : virtual Empty {
265 };
266 
267 union U3 {
268   VirtualInBase v1;
269   VirtualInBase v2;
270   VirtualInheritance v3;
271   int z;
272 };
273 
274 void take(VirtualInBase &);
275 void take(VirtualInVBase &);
276 void take(VirtualInheritance &);
277 
UnionsBarrier3(U3 & u)278 void UnionsBarrier3(U3 &u) {
279   // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
280   // CHECK-NEW: 42
281   u.z += 42;
282   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
283   // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
284   take(u.v1);
285   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
286   // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
287   take(u.v2);
288 
289   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
290   // CHECK-NEW: call void @_Z4takeR18VirtualInheritance(
291   take(u.v3);
292 }
293 
294 // CHECK-NEW-LABEL: define{{.*}} void @_Z7comparev()
compare()295 void compare() {
296   A *a = new A;
297   a->foo();
298   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
299   A *b = new (a) B;
300 
301   // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
302   // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
303   // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
304   // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
305   // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]]
306   if (a == b)
307     b->foo();
308 }
309 
310 // CHECK-NEW-LABEL: compare2
compare2(A * a,A * a2)311 bool compare2(A *a, A *a2) {
312   // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
313   // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
314   // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
315   // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
316   // CHECK-NEW: %cmp = icmp ult %struct.A* %[[a2]], %[[b2]]
317   return a < a2;
318 }
319 // CHECK-NEW-LABEL: compareIntPointers
compareIntPointers(int * a,int * b)320 bool compareIntPointers(int *a, int *b) {
321   // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
322   return a == b;
323 }
324 
325 struct HoldingOtherVirtuals {
326   B b;
327 };
328 
329 // There is no need to add barriers for comparision of pointer to classes
330 // that are not dynamic.
331 // CHECK-NEW-LABEL: compare5
compare5(HoldingOtherVirtuals * a,HoldingOtherVirtuals * b)332 bool compare5(HoldingOtherVirtuals *a, HoldingOtherVirtuals *b) {
333   // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
334   return a == b;
335 }
336 // CHECK-NEW-LABEL: compareNull
compareNull(A * a)337 bool compareNull(A *a) {
338   // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
339 
340   if (a != nullptr)
341     return false;
342   if (!a)
343     return false;
344   return a == nullptr;
345 }
346 
347 struct X;
348 // We have to also introduce the barriers if comparing pointers to incomplete
349 // objects
350 // CHECK-NEW-LABEL: define{{.*}} zeroext i1 @_Z8compare4P1XS0_
compare4(X * x,X * x2)351 bool compare4(X *x, X *x2) {
352   // CHECK-NEW: %[[x:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
353   // CHECK-NEW: %[[xp:.*]] = bitcast i8* %[[x]] to %struct.X*
354   // CHECK-NEW: %[[x2:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
355   // CHECK-NEW: %[[x2p:.*]] = bitcast i8* %[[x2]] to %struct.X*
356   // CHECK-NEW: %cmp = icmp eq %struct.X* %[[xp]], %[[x2p]]
357   return x == x2;
358 }
359 
360 // CHECK-NEW-LABEL: define{{.*}} void @_Z7member1P20HoldingOtherVirtuals(
member1(HoldingOtherVirtuals * p)361 void member1(HoldingOtherVirtuals *p) {
362 
363   // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group.p0i8(
364   (void)p->b;
365 }
366 
367 // CHECK-NEW-LABEL: member2
member2(A * a)368 void member2(A *a) {
369   // CHECK-NEW: call i8* @llvm.strip.invariant.group.p0i8
370   (void)a->m;
371 }
372 
373 // Check if from comparison of addresses of member we can't infer the equality
374 // of ap and bp.
375 // CHECK-NEW-LABEL: @_Z18testCompareMembersv(
testCompareMembers()376 void testCompareMembers() {
377   // CHECK-NEW:    [[AP:%.*]] = alloca %struct.A*
378   // CHECK-NEW:    [[APM:%.*]] = alloca i32*
379   // CHECK-NEW:    [[BP:%.*]] = alloca %struct.B*
380   // CHECK-NEW:    [[BPM:%.*]] = alloca i32*
381 
382   A *ap = new A;
383   // CHECK-NEW:   call void %{{.*}}(%struct.A* {{[^,]*}} %{{.*}})
384   ap->foo();
385   // CHECK-NEW:    [[TMP7:%.*]] = load %struct.A*, %struct.A** [[AP]]
386   // CHECK-NEW:    [[TMP8:%.*]] = bitcast %struct.A* [[TMP7]] to i8*
387   // CHECK-NEW:    [[TMP9:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP8]])
388   // CHECK-NEW:    [[TMP10:%.*]] = bitcast i8* [[TMP9]] to %struct.A*
389   // CHECK-NEW:    [[M:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP10]], i32 0, i32 1
390   // CHECK-NEW:    store i32* [[M]], i32** [[APM]]
391   int *const apm = &ap->m;
392 
393   B *bp = new (ap) B;
394 
395   // CHECK-NEW:    [[TMP20:%.*]] = load %struct.B*, %struct.B** [[BP]]
396   // CHECK-NEW:    [[TMP21:%.*]] = bitcast %struct.B* [[TMP20]] to %struct.A*
397   // CHECK-NEW:    [[TMP22:%.*]] = bitcast %struct.A* [[TMP21]] to i8*
398   // CHECK-NEW:    [[TMP23:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP22]])
399   // CHECK-NEW:    [[TMP24:%.*]] = bitcast i8* [[TMP23]] to %struct.A*
400   // CHECK-NEW:    [[M4:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP24]], i32 0, i32 1
401   // CHECK-NEW:    store i32* [[M4]], i32** [[BPM]]
402   int *const bpm = &bp->m;
403 
404   // CHECK-NEW:    [[TMP25:%.*]] = load i32*, i32** [[APM]]
405   // CHECK-NEW:    [[TMP26:%.*]] = load i32*, i32** [[BPM]]
406   // CHECK-NEW-NOT: strip.invariant.group
407   // CHECK-NEW-NOT: launder.invariant.group
408   // CHECK-NEW:    [[CMP:%.*]] = icmp eq i32* [[TMP25]], [[TMP26]]
409   if (apm == bpm) {
410     bp->foo();
411   }
412 }
413 
414 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast1P1A(%struct.A*
testCast1(A * a)415 void testCast1(A *a) {
416   // Here we get rid of dynamic info
417   // CHECK-NEW: call i8* @llvm.strip.invariant.group
418   auto *v = (void *)a;
419 
420   // CHECK-NEW: call i8* @llvm.strip.invariant.group
421   auto i2 = (uintptr_t)a;
422   (void)i2;
423 
424   // CHECK-NEW-NOT: @llvm.strip.invariant.group
425   // CHECK-NEW-NOT: @llvm.launder.invariant.group
426 
427   // The information is already stripped
428   auto i = (uintptr_t)v;
429 }
430 
431 struct Incomplete;
432 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast2P10Incomplete(%struct.Incomplete*
testCast2(Incomplete * I)433 void testCast2(Incomplete *I) {
434   // Here we get rid of potential dynamic info
435   // CHECK-NEW: call i8* @llvm.strip.invariant.group
436   auto *v = (void *)I;
437 
438   // CHECK-NEW: call i8* @llvm.strip.invariant.group
439   auto i2 = (uintptr_t)I;
440   (void)i2;
441 
442   // CHECK-NEW-NOT: @llvm.strip.invariant.group
443   // CHECK-NEW-NOT: @llvm.launder.invariant.group
444 
445   // The information is already stripped
446   auto i = (uintptr_t)v;
447 }
448 
449 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast3y(
testCast3(uintptr_t i)450 void testCast3(uintptr_t i) {
451   // CHECK-NEW-NOT: @llvm.strip.invariant.group
452   // CHECK-NEW: @llvm.launder.invariant.group
453   A *a3 = (A *)i;
454   (void)a3;
455 
456   auto *v2 = (void *)i;
457 
458   // CHECK-NEW: @llvm.launder.invariant.group
459   A *a2 = (A *)v2;
460   (void)a2;
461 
462   // CHECK-NEW-NOT: @llvm.launder.invariant.group
463   auto *v3 = (void *)i;
464   (void)v3;
465 }
466 
467 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast4y(
testCast4(uintptr_t i)468 void testCast4(uintptr_t i) {
469   // CHECK-NEW-NOT: @llvm.strip.invariant.group
470   // CHECK-NEW: @llvm.launder.invariant.group
471   auto *a3 = (Incomplete *)i;
472   (void)a3;
473 
474   // CHECK-NEW: @llvm.launder.invariant.group
475   auto *v2 = (void *)i;
476   // CHECK-NEW-NOT: @llvm.launder.invariant.group
477   auto *a2 = (Incomplete *)v2;
478   (void)a2;
479 }
480 
481 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast5P1B(
testCast5(B * b)482 void testCast5(B *b) {
483   // CHECK-NEW-NOT: @llvm.strip.invariant.group
484   // CHECK-NEW-NOT: @llvm.launder.invariant.group
485   A *a = b;
486   (void)a;
487 
488   auto *b2 = (B *)a;
489   (void)b2;
490 }
491 
492 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast6P1A(
testCast6(A * a)493 void testCast6(A *a) {
494 
495   // CHECK-NEW: @llvm.strip.invariant.group
496   auto *I = (Incomplete *)a;
497   (void)I;
498   // CHECK-NEW: @llvm.launder.invariant.group
499   auto *a2 = (A *)I;
500   (void)a2;
501 
502   // CHECK-NEW: @llvm.strip.invariant.group
503   auto *E = (Empty *)a;
504   (void)E;
505 
506   // CHECK-NEW: @llvm.launder.invariant.group
507   auto *a3 = (A *)E;
508   (void)a3;
509 
510   // CHECK-NEW-NOT: @llvm.strip.invariant.group
511   auto i = (uintptr_t)E;
512   (void)i;
513 }
514 
515 class Incomplete2;
516 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast7P10Incomplete(
testCast7(Incomplete * I)517 void testCast7(Incomplete *I) {
518   // CHECK-NEW-NOT: @llvm.strip.invariant.group
519 
520   // Incomplete2 could be dynamic where Incomplete may not be dynamic, thus
521   // launder is needed.  We don't strip firstly because launder is sufficient.
522 
523   // CHECK-NEW: @llvm.launder.invariant.group
524   auto *I2 = (Incomplete2 *)I;
525   (void)I2;
526   // CHECK-NEW-LABEL: ret void
527 }
528 
529 template <typename Base>
530 struct PossiblyDerivingFromDynamicBase : Base {
531 };
532 
533 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast8P10Incomplete(
testCast8(Incomplete * I)534 void testCast8(Incomplete *I) {
535   // CHECK-NEW-NOT: @llvm.strip.invariant.group
536   // CHECK-NEW: @llvm.launder.invariant.group
537   auto *P = (PossiblyDerivingFromDynamicBase<Incomplete> *)I;
538   (void)P;
539 
540   // CHECK-NEW: @llvm.launder.invariant.group
541   auto *P2 = (PossiblyDerivingFromDynamicBase<Empty> *)I;
542   (void)P2;
543 
544   // CHECK-NEW: @llvm.launder.invariant.group
545   auto *P3 = (PossiblyDerivingFromDynamicBase<A> *)I;
546   (void)P3;
547 
548   // CHECK-NEW-NOT: @llvm.launder.invariant.group
549   auto *a3 = (A *)P3;
550 
551   // CHECK-NEW-LABEL: ret void
552 }
553 
554 // CHECK-NEW-LABEL: define{{.*}} void @_Z9testCast9
testCast9(PossiblyDerivingFromDynamicBase<Incomplete> * P)555 void testCast9(PossiblyDerivingFromDynamicBase<Incomplete> *P) {
556   // CHECK-NEW: @llvm.strip.invariant.group
557   auto *V = (void *)P;
558 
559   // CHECK-NEW-LABEL: ret void
560 }
561 
562 /** DTORS **/
563 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
564 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
565 // CHECK-DTORS-LABEL: {{^}}}
566 
567 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev(
568 // CHECK-DTORS-NOT: invariant.barrier
569 // CHECK-DTORS-LABEL: {{^}}}
570 
571 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
572 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
573 // CHECK-DTORS-LABEL: {{^}}}
574 
575 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
576 
577 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
578 // CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
579 // CHECK-DTORS-LABEL: {{^}}}
580 
581 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
582 // CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
583 // CHECK-DTORS-LABEL: {{^}}}
584 
585 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
586 // CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
587 // CHECK-DTORS-LABEL: {{^}}}
588 
589 // CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:[0-9]+]], ![[SEC:[0-9]+]]{{.*}}}
590 
591 // CHECK-LINK-REQ: ![[FIRST]] = !{i32 1, !"StrictVTablePointers", i32 1}
592 // CHECK-LINK-REQ: ![[SEC]] = !{i32 3, !"StrictVTablePointersRequirement", ![[META:.*]]}
593 // CHECK-LINK-REQ: ![[META]] = !{!"StrictVTablePointers", i32 1}
594