| // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s |
| |
| struct A { |
| A(const A&); |
| A(); |
| ~A(); |
| }; |
| |
| struct B : public A { |
| B(); |
| B(const B& Other); |
| ~B(); |
| }; |
| |
| struct C : public B { |
| C(); |
| C(const C& Other); |
| ~C(); |
| }; |
| |
| struct X { |
| operator B&(); |
| operator C&(); |
| X(const X&); |
| X(); |
| ~X(); |
| B b; |
| C c; |
| }; |
| |
| void test0_helper(A); |
| void test0(X x) { |
| test0_helper(x); |
| // CHECK-LABEL: define{{.*}} void @_Z5test01X( |
| // CHECK-SAME: ptr noundef [[ARG:%.*]]) |
| // CHECK: [[ARG_ADDR:%.*]] = alloca ptr |
| // CHECK-NEXT: [[TMP:%.*]] = alloca [[A:%.*]], align |
| // CHECK-NEXT: store ptr [[ARG]], ptr [[ARG_ADDR]] |
| // CHECK-NEXT: [[T0:%.*]] = call noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN1XcvR1BEv( |
| // CHECK-NEXT: call void @_ZN1AC1ERKS_(ptr {{[^,]*}} [[TMP]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[T0]]) |
| // CHECK-NEXT: call void @_Z12test0_helper1A(ptr noundef [[TMP]]) |
| // CHECK-NEXT: call void @_ZN1AD1Ev(ptr {{[^,]*}} [[TMP]]) |
| // CHECK-NEXT: ret void |
| } |
| |
| struct Base; |
| |
| struct Root { |
| operator Base&(); |
| }; |
| |
| struct Derived; |
| |
| struct Base : Root { |
| Base(const Base &); |
| Base(); |
| operator Derived &(); |
| }; |
| |
| struct Derived : Base { |
| }; |
| |
| void test1_helper(Base); |
| void test1(Derived bb) { |
| // CHECK-LABEL: define{{.*}} void @_Z5test17Derived( |
| // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv( |
| // CHECK: call void @_ZN4BaseC1ERKS_( |
| // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv( |
| // CHECK: call void @_Z12test1_helper4Base( |
| test1_helper(bb); |
| } |
| |
| // Don't crash after devirtualizing a derived-to-base conversion |
| // to an empty base allocated at offset zero. |
| // rdar://problem/11993704 |
| class Test2a {}; |
| class Test2b final : public virtual Test2a {}; |
| void test2(Test2b &x) { |
| Test2a &y = x; |
| // CHECK-LABEL: define{{.*}} void @_Z5test2R6Test2b( |
| // CHECK: [[X:%.*]] = alloca ptr, align 8 |
| // CHECK-NEXT: [[Y:%.*]] = alloca ptr, align 8 |
| // CHECK-NEXT: store ptr {{%.*}}, ptr [[X]], align 8 |
| // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]], align 8 |
| // CHECK-NEXT: store ptr [[T0]], ptr [[Y]], align 8 |
| // CHECK-NEXT: ret void |
| } |