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
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
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
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
);
81 // Ensure we mark the B vtable as used here, because we're going to emit a
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
); }