1// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
2
3struct A {
4  A(const A&);
5  A();
6  ~A();
7};
8
9struct B : public A {
10  B();
11  B(const B& Other);
12  ~B();
13};
14
15struct C : public B {
16  C();
17  C(const C& Other);
18  ~C();
19};
20
21struct X {
22  operator B&();
23  operator C&();
24  X(const X&);
25  X();
26  ~X();
27  B b;
28  C c;
29};
30
31void test0_helper(A);
32void test0(X x) {
33  test0_helper(x);
34  // CHECK-LABEL:    define void @_Z5test01X(
35  // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align
36  // CHECK-NEXT: [[T0:%.*]] = call nonnull [[B:%.*]]* @_ZN1XcvR1BEv(
37  // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
38  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* nonnull [[T1]])
39  // CHECK-NEXT: call void @_Z12test0_helper1A([[A]]* [[TMP]])
40  // CHECK-NEXT: call void @_ZN1AD1Ev([[A]]* [[TMP]])
41  // CHECK-NEXT: ret void
42}
43
44struct Base;
45
46struct Root {
47  operator Base&();
48};
49
50struct Derived;
51
52struct Base : Root {
53  Base(const Base &);
54  Base();
55  operator Derived &();
56};
57
58struct Derived : Base {
59};
60
61void test1_helper(Base);
62void test1(Derived bb) {
63  // CHECK-LABEL:     define void @_Z5test17Derived(
64  // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
65  // CHECK:     call void @_ZN4BaseC1ERKS_(
66  // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
67  // CHECK:     call void @_Z12test1_helper4Base(
68  test1_helper(bb);
69}
70
71// Don't crash after devirtualizing a derived-to-base conversion
72// to an empty base allocated at offset zero.
73// rdar://problem/11993704
74class Test2a {};
75class Test2b final : public virtual Test2a {};
76void test2(Test2b &x) {
77  Test2a &y = x;
78  // CHECK-LABEL:    define void @_Z5test2R6Test2b(
79  // CHECK:      [[X:%.*]] = alloca [[B:%.*]]*, align 8
80  // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]]*, align 8
81  // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]], align 8
82  // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]], align 8
83  // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
84  // CHECK-NEXT: store [[A]]* [[T1]], [[A]]** [[Y]], align 8
85  // CHECK-NEXT: ret void
86}
87