[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / CodeGenCXX / dynamic-cast-exact.cpp
blobbd283e85101b4b6dfeece4a89a41af6cc328d2d9
1 // RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - -O1 -disable-llvm-passes | FileCheck %s --implicit-check-not='call {{.*}} @__dynamic_cast'
2 struct Offset { virtual ~Offset(); };
3 struct A { virtual ~A(); };
4 struct B final : Offset, A { };
6 struct C { virtual ~C(); int c; };
7 struct D : A { int d; };
8 struct E : A { int e; };
9 struct F : virtual A { int f; };
10 struct G : virtual A { int g; };
11 struct H final : C, D, E, F, G { int h; };
13 // CHECK-LABEL: @_Z7inexactP1A
14 C *inexact(A *a) {
15 // CHECK: call {{.*}} @__dynamic_cast
16 return dynamic_cast<C*>(a);
19 // CHECK-LABEL: @_Z12exact_singleP1A
20 B *exact_single(A *a) {
21 // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null
22 // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]
24 // CHECK: [[LABEL_NOTNULL]]:
25 // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]
26 // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 1, i32 2)
27 // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -8
28 // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]
30 // CHECK: [[LABEL_FAILED]]:
31 // CHECK: br label %[[LABEL_END]]
33 // CHECK: [[LABEL_END]]:
34 // CHECK: phi ptr [ %[[RESULT]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_FAILED]] ]
35 return dynamic_cast<B*>(a);
38 // CHECK-LABEL: @_Z9exact_refR1A
39 B &exact_ref(A &a) {
40 // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null
41 // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]
43 // CHECK: [[LABEL_NOTNULL]]:
44 // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]
45 // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 1, i32 2)
46 // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -8
47 // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]
49 // CHECK: [[LABEL_FAILED]]:
50 // CHECK: call {{.*}} @__cxa_bad_cast
51 // CHECK: unreachable
53 // CHECK: [[LABEL_END]]:
54 // CHECK: ret ptr %[[RESULT]]
55 return dynamic_cast<B&>(a);
58 // CHECK-LABEL: @_Z11exact_multiP1A
59 H *exact_multi(A *a) {
60 // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null
61 // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]
63 // CHECK: [[LABEL_NOTNULL]]:
64 // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]
65 // CHECK: %[[OFFSET_TO_TOP_SLOT:.*]] = getelementptr inbounds i64, ptr %[[VPTR]], i64 -2
66 // CHECK: %[[OFFSET_TO_TOP:.*]] = load i64, ptr %[[OFFSET_TO_TOP_SLOT]]
67 // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 %[[OFFSET_TO_TOP]]
68 // CHECK: %[[DERIVED_VPTR:.*]] = load ptr, ptr %[[RESULT]]
69 // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[DERIVED_VPTR]], getelementptr inbounds ({ [5 x ptr], [4 x ptr], [4 x ptr], [6 x ptr], [6 x ptr] }, ptr @_ZTV1H, i32 0, inrange i32 0, i32 3)
70 // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]
72 // CHECK: [[LABEL_FAILED]]:
73 // CHECK: br label %[[LABEL_END]]
75 // CHECK: [[LABEL_END]]:
76 // CHECK: phi ptr [ %[[RESULT]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_FAILED]] ]
77 return dynamic_cast<H*>(a);
80 namespace GH64088 {
81 // Ensure we mark the B vtable as used here, because we're going to emit a
82 // reference to it.
83 // CHECK: define {{.*}} @_ZN7GH640881BD0
84 struct A { virtual ~A(); };
85 struct B final : A { virtual ~B() = default; };
86 B *cast(A *p) { return dynamic_cast<B*>(p); }