diff options
Diffstat (limited to 'test/CodeGenCXX')
55 files changed, 1011 insertions, 444 deletions
diff --git a/test/CodeGenCXX/PR5863-unreachable-block.cpp b/test/CodeGenCXX/PR5863-unreachable-block.cpp index 4829b52..3f32d75 100644 --- a/test/CodeGenCXX/PR5863-unreachable-block.cpp +++ b/test/CodeGenCXX/PR5863-unreachable-block.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -emit-llvm-only %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only %s // PR5863 class E { }; diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp index 0198ed0..32e17a3 100644 --- a/test/CodeGenCXX/anonymous-namespaces.cpp +++ b/test/CodeGenCXX/anonymous-namespaces.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t // RUN: FileCheck %s -check-prefix=1 < %t // RUN: FileCheck %s -check-prefix=2 < %t diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index 85e931b..2ddafec 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -106,14 +106,11 @@ struct S { } s; - //PR8760 - template <typename T>
- struct Foo {
- Foo() : ptr(__nullptr) {}
- union {
- T *ptr;
- };
- };
- Foo<int> f;
-
-
+//PR8760 +template <typename T> struct Foo { + Foo() : ptr(__nullptr) {} + union { + T *ptr; + }; +}; +Foo<int> f; diff --git a/test/CodeGenCXX/apple-kext-guard-variable.cpp b/test/CodeGenCXX/apple-kext-guard-variable.cpp new file mode 100644 index 0000000..26b0d14 --- /dev/null +++ b/test/CodeGenCXX/apple-kext-guard-variable.cpp @@ -0,0 +1,9 @@ +// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -o %t.s -mkernel -Xclang -verify %s + +// rdar://problem/9143356 + +int foo(); +void test() { + static int y = 0; + static int x = foo(); // expected-error {{this initialization requires a guard variable, which the kernel does not support}} +} diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index 672ca01..8d74d00 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -117,7 +117,8 @@ namespace test3 { // CHECK: [[N:%.*]] = load i32* // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) - // CHECK: [[SZ:%.*]] = select + // CHECK: [[OR:%.*]] = or i1 + // CHECK: [[SZ:%.*]] = select i1 [[OR]] // CHECK: call noalias i8* @_Znam(i32 [[SZ]]) // CHECK: store i32 4 // CHECK: store i32 [[N]] diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp index ea174b5..a4d5b86 100644 --- a/test/CodeGenCXX/blocks.cpp +++ b/test/CodeGenCXX/blocks.cpp @@ -55,3 +55,52 @@ namespace test1 { // ...or non-trivial copy constructors, but it's not clear how to do // that and still have a constant initializer in '03. } + +namespace test2 { + struct A { + A(); + A(const A &); + ~A(); + }; + + struct B { + B(); + B(const B &); + ~B(); + }; + + // CHECK: define void @_ZN5test24testEv() + void test() { + __block A a; + __block B b; + } + + // CHECK: define internal void @__Block_byref_object_copy + // CHECK: call void @_ZN5test21AC1ERKS0_( + + // CHECK: define internal void @__Block_byref_object_dispose + // CHECK: call void @_ZN5test21AD1Ev( + + // CHECK: define internal void @__Block_byref_object_copy + // CHECK: call void @_ZN5test21BC1ERKS0_( + + // CHECK: define internal void @__Block_byref_object_dispose + // CHECK: call void @_ZN5test21BD1Ev( +} + +// rdar://problem/9334739 +// Make sure we mark destructors for parameters captured in blocks. +namespace test3 { + struct A { + A(const A&); + ~A(); + }; + + struct B : A { + }; + + void test(B b) { + extern void consume(void(^)()); + consume(^{ (void) b; }); + } +} diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp index 6675b49..96fbae8 100644 --- a/test/CodeGenCXX/class-layout.cpp +++ b/test/CodeGenCXX/class-layout.cpp @@ -17,3 +17,31 @@ namespace Test3 { // CHECK: %"struct.Test3::A" = type { i32 (...)**, i32 } struct A { virtual void f(); int a; } *a; } + +namespace Test4 { + // Test from PR5589. + // CHECK: %"struct.Test4::A" = type { i32, i8, float } + // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double } + struct A { + int a; + char c; + float b; + }; + struct B : public A { + short d; + double e; + } *b; +} + +namespace Test5 { + struct A { + virtual void f(); + char a; + }; + + // CHECK: %"struct.Test5::B" = type { [9 x i8], i8, i8, [5 x i8] } + struct B : A { + char b : 1; + char c; + } *b; +} diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp new file mode 100644 index 0000000..5b432c7 --- /dev/null +++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++0x -o - %s | FileCheck %s + +struct non_trivial { + non_trivial(); + ~non_trivial(); +}; +non_trivial::non_trivial() {} +non_trivial::~non_trivial() {} + +// We use a virtual base to ensure that the constructor +// delegation optimization (complete->base) can't be +// performed. +struct delegator { + non_trivial n; + delegator(); + delegator(int); + delegator(char); + delegator(bool); +}; + +delegator::delegator() { + throw 0; +} + +// CHECK: define void @_ZN9delegatorC1Ei +// CHECK: call void @_ZN9delegatorC1Ev +// CHECK-NOT: lpad +// CHECK: ret +// CHECK-NOT: lpad +// CHECK: define void @_ZN9delegatorC2Ei +// CHECK: call void @_ZN9delegatorC2Ev +// CHECK-NOT: lpad +// CHECK: ret +// CHECK-NOT: lpad +delegator::delegator(int) + : delegator() +{} + +delegator::delegator(bool) +{} + +// CHECK: define void @_ZN9delegatorC2Ec +// CHECK: call void @_ZN9delegatorC2Eb +// CHECK: call void @__cxa_throw +delegator::delegator(char) + : delegator(true) { + throw 0; +} diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp index c99518e..f0cb6d6 100644 --- a/test/CodeGenCXX/debug-info-byval.cpp +++ b/test/CodeGenCXX/debug-info-byval.cpp @@ -1,5 +1,5 @@ // RUN: %clang -g -S %s -o - | FileCheck %s -// Test to check presense of debug info for byval parameter. +// Test to check presence of debug info for byval parameter. // Radar 8350436. class DAG { public: diff --git a/test/CodeGenCXX/debug-info-cxx0x.cpp b/test/CodeGenCXX/debug-info-cxx0x.cpp new file mode 100644 index 0000000..5753b05 --- /dev/null +++ b/test/CodeGenCXX/debug-info-cxx0x.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm-only -std=c++0x -g %s + +namespace PR9414 { + int f() { + auto x = 0; + return x; + } +} diff --git a/test/CodeGenCXX/debug-info-fn-template.cpp b/test/CodeGenCXX/debug-info-fn-template.cpp new file mode 100644 index 0000000..c8291af --- /dev/null +++ b/test/CodeGenCXX/debug-info-fn-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +template<typename T> +struct XF { + T member; +}; + +template<typename T> +T fx(XF<T> xi) { + return xi.member; +} + +//CHECK: DW_TAG_template_type_parameter +//CHECK: XF<int> +template int fx(XF<int>); diff --git a/test/CodeGenCXX/debug-info-method-spec.cpp b/test/CodeGenCXX/debug-info-method-spec.cpp new file mode 100644 index 0000000..31f6663 --- /dev/null +++ b/test/CodeGenCXX/debug-info-method-spec.cpp @@ -0,0 +1,10 @@ +// RUN: %clang -fverbose-asm -cc1 -g -S %s -o - | grep DW_AT_specification +// Radar 9254491 +class A { +public: + void doSomething(int i) { ++i; } +}; + +void foo(A *a) { + a->doSomething(2); +} diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 2e0a96d..27f5eae 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -g -S %s -o - | FileCheck %s +// RUN: %clang -g -S -fverbose-asm %s -o - | FileCheck %s // CHECK: TAG_namespace namespace A { diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp index 0ddfc24..9d52159 100644 --- a/test/CodeGenCXX/debug-info-template.cpp +++ b/test/CodeGenCXX/debug-info-template.cpp @@ -20,3 +20,27 @@ class TU { }; TU<2> u2; + +// PR9600 +template<typename T> class vector {}; +class Foo; +typedef vector<Foo*> FooVector[3]; +struct Test { + virtual void foo(FooVector *); +}; +static Test test; + +// PR9608 +template <int i> struct TheTemplate { + struct Empty2 {}; + typedef const Empty2 DependentType[i]; + TheTemplate() {} +}; + +class TheTemplateTest : public TheTemplate<42> { + TheTemplateTest(); + void method(const TheTemplate<42>::DependentType *) {} +}; + +TheTemplateTest::TheTemplateTest() : TheTemplate<42>() {} + diff --git a/test/CodeGenCXX/debug-info-this.cpp b/test/CodeGenCXX/debug-info-this.cpp new file mode 100644 index 0000000..a2842d0 --- /dev/null +++ b/test/CodeGenCXX/debug-info-this.cpp @@ -0,0 +1,15 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +// Radar 9239104 +class Class +{ +public: +//CHECK: DW_TAG_const_type + int foo (int p) const { + return p+m_int; + } + +protected: + int m_int; +}; + +Class c; diff --git a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp index e332f40..0e15302 100644 --- a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp +++ b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s struct A { int i; }; -struct B { int j; }; +struct B { char j; }; struct C : A, B { int k; }; struct D final : virtual C { diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index f382413..353b610 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | FileCheck %s // CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev // CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp index 74795b5..5eede66 100644 --- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp +++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp @@ -2,7 +2,8 @@ struct A { virtual void f(); - + virtual void f_const() const; + A h(); }; @@ -28,6 +29,12 @@ void f(A a, A *ap, A& ar) { // CHECK: call void @_ZN1A1fEv a.h().f(); + + // CHECK: call void @_ZNK1A7f_constEv + a.f_const(); + + // CHECK: call void @_ZN1A1fEv + (a).f(); } struct B { @@ -45,3 +52,4 @@ void f() { // CHECK: call void @_ZN1B1fEv B().h().f(); } + diff --git a/test/CodeGenCXX/dynamic-cast-always-null.cpp b/test/CodeGenCXX/dynamic-cast-always-null.cpp new file mode 100644 index 0000000..e4e8694 --- /dev/null +++ b/test/CodeGenCXX/dynamic-cast-always-null.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++0x -o - | FileCheck %s +struct A { virtual ~A(); }; +struct B final : A { }; +struct C { virtual ~C(); int c; }; + +// CHECK: @_Z1fP1B +C *f(B* b) { + // CHECK-NOT: call i8* @__dynamic_cast + // CHECK: ret %struct.C* null + return dynamic_cast<C*>(b); +} + +// CHECK: @_Z1fR1B +C &f(B& b) { + // CHECK-NOT: call i8* @__dynamic_cast + // CHECK: call void @__cxa_bad_cast() noreturn + // CHECK: ret %struct.C* undef + return dynamic_cast<C&>(b); +} diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp index 9838e25..e84bb9b 100644 --- a/test/CodeGenCXX/dynamic-cast.cpp +++ b/test/CodeGenCXX/dynamic-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - | FileCheck %s +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s struct A { virtual void f(); }; struct B : A { }; diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp deleted file mode 100644 index 7fd5899..0000000 --- a/test/CodeGenCXX/dyncast.cpp +++ /dev/null @@ -1,367 +0,0 @@ -// RUN: %clang_cc1 -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll -// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s - -#include <typeinfo> - -class test1_A { virtual void f() { } }; -class test1_B { virtual void g() { } }; -class test1_D : public virtual test1_A, private test1_B {}; -class test1_E : public test1_D, public test1_B {}; -class test1_F : public test1_E, public test1_D {}; - -extern test1_D test1_d; -extern test1_F test1_f; - -extern "C" int printf(const char *str...); - -#define S(V, N) if (V) printf("PASS: %d\n", N); else printf("FAIL: %d\n", N) - -void test1() { - test1_B* bp = (test1_B*)&test1_d; - test1_A* ap = &test1_d; - test1_D* dp = dynamic_cast<test1_D*>(bp); - S(dp == 0, 1); - ap = dynamic_cast<test1_A*>(bp); - S(ap == 0, 2); - bp = dynamic_cast<test1_B*>(ap); - S(bp == 0, 3); - ap = dynamic_cast<test1_A*>(&test1_d); - S(ap != 0, 4); - // FIXME: Doesn't work yet, gcc fails this at compile time. We'd need access - // control for this to work. - // bp = dynamic_cast<test1_B*>(&test1_d); - // S(bp == 0, 5); - { - test1_A* ap = &test1_f; - S(ap != 0, 6); - test1_D* dp = dynamic_cast<test1_D*>(ap); - S(dp == 0, 7); - // cast from virtual base - test1_E* ep1 = dynamic_cast<test1_E*>(ap); - S(ep1 != 0, 8); - } - dp = dynamic_cast<test1_D*>(&test1_d); - S(dp == &test1_d, 9); - const test1_D *cdp = dynamic_cast<const test1_D*>(&test1_d); - S(cdp == &test1_d, 10); - dp = dynamic_cast<test1_D*>((test1_A*)0); - S(dp == 0, 11); - ap = dynamic_cast<test1_A*>(&test1_d); - S(ap == (test1_A*)&test1_d, 12); - test1_E* ep = dynamic_cast<test1_E*>(&test1_f); - S(ep == (test1_E*)&test1_f, 13); - void *vp = dynamic_cast<void*>(ap); - S(vp == &test1_d, 14); - const void *cvp = dynamic_cast<const void*>(ap); - S(cvp == &test1_d, 15); -} - -// CHECK-LL: define void @_Z5test1v() nounwind { -// CHECK-LL: [[bp:%.*]] = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: [[ap:%.*]] = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: [[dp:%.*]] = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: [[ap37:%.*]] = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: [[dp53:%.*]] = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: [[ep1:%.*]] = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: [[cdp:%.*]] = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: [[ep:%.*]] = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: [[vp:%.*]] = alloca i8*, align 8 -// CHECK-LL-NEXT: [[cvp:%.*]] = alloca i8*, align 8 -// CHECK-LL-NEXT: store %class.test1_A* bitcast (%class.test1_D* @test1_d to %class.test1_A*), %class.test1_A** [[bp]] -// CHECK-LL-NEXT: br i1 false, label %[[castnull2:.*]], label %[[castnotnull1:.*]] -// CHECK-LL: [[castnotnull1]] -// CHECK-LL-NEXT: [[vtable:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: [[vbaseoffsetptr:%.*]] = getelementptr i8* [[vtable]], i64 -24 -// CHECK-LL-NEXT: [[v1:%.*]] = bitcast i8* [[vbaseoffsetptr]] to i64* -// CHECK-LL-NEXT: [[vbaseoffset:%.*]] = load i64* [[v1]] -// CHECK-LL-NEXT: [[addptr:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset:.*]] -// CHECK-LL-NEXT: [[v2:%.*]] = bitcast i8* [[addptr]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[castend3:.*]] -// CHECK-LL: [[castnull2]] -// CHECK-LL-NEXT: br label %[[castend3]] -// CHECK-LL: [[castend3]] -// CHECK-LL-NEXT: [[v3:%.*]] = phi %class.test1_A* [ [[v2]], %[[castnotnull1]] ], [ null, %[[castnull2]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v3]], %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[tmp:%.*]] = load %class.test1_A** [[bp]] -// CHECK-LL-NEXT: [[v4:%.*]] = icmp ne %class.test1_A* [[tmp]], null -// CHECK-LL-NEXT: br i1 [[v4]], label %[[v5:.*]], label %[[v9:.*]] -// CHECK-LL: [[v6:%.*]] = bitcast %class.test1_A* [[tmp]] to i8* -// CHECK-LL-NEXT: [[v7:%.*]] = call i8* @__dynamic_cast(i8* [[v6]], i8* bitcast (%0* @_ZTI7test1_B to i8*), i8* bitcast (%1* @_ZTI7test1_D to i8*), i64 -1) -// CHECK-LL-NEXT: [[v8:%.*]] = bitcast i8* [[v7]] to %class.test1_D* -// CHECK-LL-NEXT: br label %[[v10:.*]] -// CHECK-LL: br label %[[v10]] -// CHECK-LL: [[v11:%.*]] = phi %class.test1_D* [ [[v8]], %[[v5]] ], [ null, %[[v9]] ] -// CHECK-LL-NEXT: store %class.test1_D* [[v11]], %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[tmp4:%.*]] = load %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[cmp:%.*]] = icmp eq %class.test1_D* [[tmp4]], null -// CHECK-LL-NEXT: br i1 [[cmp]], label %[[ifthen:.*]], label %[[ifelse:.*]] -// CHECK-LL: [[ifthen]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 1) -// CHECK-LL-NEXT: br label %[[ifend:.*]] -// CHECK-LL: [[ifelse]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 1) -// CHECK-LL-NEXT: br label %[[ifend]] -// CHECK-LL: [[ifend]] -// CHECK-LL-NEXT: [[tmp6:%.*]] = load %class.test1_A** [[bp]] -// CHECK-LL-NEXT: [[v12:%.*]] = icmp ne %class.test1_A* [[tmp6]], null -// CHECK-LL-NEXT: br i1 [[v12]], label %[[v13:.*]], label %[[v17:.*]] -// CHECK-LL: [[v14:%.*]] = bitcast %class.test1_A* [[tmp6]] to i8* -// CHECK-LL-NEXT: [[v15:%.*]] = call i8* @__dynamic_cast(i8* [[v14]], i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i64 -1) -// CHECK-LL-NEXT: [[v16:%.*]] = bitcast i8* [[v15]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[v18:.*]] -// CHECK-LL: br label %[[v18]] -// CHECK-LL: [[v19:%.*]] = phi %class.test1_A* [ [[v16]], %[[v13]] ], [ null, %[[v17]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v19]], %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[tmp7:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[cmp8:%.*]] = icmp eq %class.test1_A* [[tmp7]], null -// CHECK-LL-NEXT: br i1 [[cmp8]], label %[[ifthen9:.*]], label %[[ifelse11:.*]] -// CHECK-LL: [[ifthen9]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 2) -// CHECK-LL-NEXT: br label %[[ifend13:.*]] -// CHECK-LL: [[ifelse11]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 2) -// CHECK-LL-NEXT: br label %[[ifend13]] -// CHECK-LL: [[ifend13]] -// CHECK-LL-NEXT: [[tmp14:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[v20:%.*]] = icmp ne %class.test1_A* [[tmp14]], null -// CHECK-LL-NEXT: br i1 [[v20]], label %[[v21:.*]], label %[[v25:.*]] -// CHECK-LL: [[v22:%.*]] = bitcast %class.test1_A* [[tmp14]] to i8* -// CHECK-LL-NEXT: [[v23:%.*]] = call i8* @__dynamic_cast({{.*}} [[v22]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_B to i8*), i64 -1) -// CHECK-LL-NEXT: [[v24:%.*]] = bitcast i8* [[v23]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[v26:.*]] -// CHECK-LL: br label %[[v26]] -// CHECK-LL: [[v27:%.*]] = phi %class.test1_A* [ [[v24]], %[[v21]] ], [ null, %[[v25]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v27]], %class.test1_A** [[bp]] -// CHECK-LL-NEXT: [[tmp15:%.*]] = load %class.test1_A** [[bp]] -// CHECK-LL-NEXT: [[cmp16:%.*]] = icmp eq %class.test1_A* [[tmp15]], null -// CHECK-LL-NEXT: br i1 [[cmp16]], label %[[ifthen17:.*]], label %[[ifelse19:.*]] -// CHECK-LL: [[ifthen17]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 3) -// CHECK-LL-NEXT: br label %[[ifend21:.*]] -// CHECK-LL: [[ifelse19]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 3) -// CHECK-LL-NEXT: br label %[[ifend21]] -// CHECK-LL: [[ifend21]] -// CHECK-LL-NEXT: br i1 false, label %[[castnull27:.*]], label %[[castnotnull22:.*]] -// CHECK-LL: [[castnotnull22]] -// CHECK-LL-NEXT: [[vtable23:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: [[vbaseoffsetptr24:%.*]] = getelementptr i8* [[vtable23]], i64 -24 -// CHECK-LL-NEXT: [[v28:%.*]] = bitcast i8* [[vbaseoffsetptr24]] to i64* -// CHECK-LL-NEXT: [[vbaseoffset25:%.*]] = load i64* [[v28]] -// CHECK-LL-NEXT: [[addptr26:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset25]] -// CHECK-LL-NEXT: [[v29:%.*]] = bitcast i8* [[addptr26]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[castend28:.*]] -// CHECK-LL: [[castnull27]] -// CHECK-LL-NEXT: br label %[[castend28]] -// CHECK-LL: [[castend28]] -// CHECK-LL-NEXT: [[v30:%.*]] = phi %class.test1_A* [ [[v29]], %[[castnotnull22]] ], [ null, %[[castnull27]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v30]], %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[tmp29:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[cmp30:%.*]] = icmp ne %class.test1_A* [[tmp29]], null -// CHECK-LL-NEXT: br i1 [[cmp30]], label %[[ifthen31:.*]], label %[[ifelse33:.*]] -// CHECK-LL: [[ifthen31]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 4) -// CHECK-LL-NEXT: br label %[[ifend35:.*]] -// CHECK-LL: [[ifelse33]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 4) -// CHECK-LL-NEXT: br label %[[ifend35]] -// CHECK-LL: [[ifend35]] -// CHECK-LL-NEXT: br i1 false, label %[[castnull43:.*]], label %[[castnotnull38:.*]] -// CHECK-LL: [[castnotnull38]] -// CHECK-LL-NEXT: [[vtable39:%.*]] = load i8** bitcast (%class.test1_F* @test1_f to i8**) -// CHECK-LL-NEXT: [[vbaseoffsetptr40:%.*]] = getelementptr i8* [[vtable39]], i64 -24 -// CHECK-LL-NEXT: [[v31:%.*]] = bitcast i8* [[vbaseoffsetptr40]] to i64* -// CHECK-LL-NEXT: [[vbaseoffset41:%.*]] = load i64* [[v31]] -// CHECK-LL-NEXT: [[addptr42:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_F* @test1_f, i32 0, i32 0, i32 0), i64 [[vbaseoffset41]] -// CHECK-LL-NEXT: [[v32:%.*]] = bitcast i8* [[addptr42]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[castend44:.*]] -// CHECK-LL: [[castnull43]] -// CHECK-LL-NEXT: br label %[[castend44]] -// CHECK-LL: [[castend44]] -// CHECK-LL-NEXT: [[v33:%.*]] = phi %class.test1_A* [ [[v32]], %[[castnotnull38]] ], [ null, %[[castnull43]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v33]], %class.test1_A** [[ap37]] -// CHECK-LL-NEXT: [[tmp45:%.*]] = load %class.test1_A** [[ap37]] -// CHECK-LL-NEXT: [[cmp46:%.*]] = icmp ne %class.test1_A* [[tmp45]], null -// CHECK-LL-NEXT: br i1 [[cmp46]], label %[[ifthen47:.*]], label %[[ifelse49:.*]] -// CHECK-LL: [[ifthen47]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 6) -// CHECK-LL-NEXT: br label %[[ifend51:.*]] -// CHECK-LL: [[ifelse49]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 6) -// CHECK-LL-NEXT: br label %[[ifend51]] -// CHECK-LL: [[ifend51]] -// CHECK-LL-NEXT: [[tmp54:%.*]] = load %class.test1_A** [[ap37]] -// CHECK-LL-NEXT: [[v34:%.*]] = icmp ne %class.test1_A* [[tmp54]], null -// CHECK-LL-NEXT: br i1 [[v34]], label %[[v35:.*]], label %[[v39:.*]] -// CHECK-LL: [[v36:%.*]] = bitcast %class.test1_A* [[tmp54]] to i8* -// CHECK-LL-NEXT: [[v37:%.*]] = call i8* @__dynamic_cast(i8* [[v36]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) -// CHECK-LL-NEXT: [[v38:%.*]] = bitcast i8* [[v37]] to %class.test1_D* -// CHECK-LL-NEXT: br label %[[v40:.*]] -// CHECK-LL: br label %[[v40]] -// CHECK-LL: [[v41:%.*]] = phi %class.test1_D* [ [[v38]], %[[v35]] ], [ null, %[[v39]] ] -// CHECK-LL-NEXT: store %class.test1_D* [[v41]], %class.test1_D** [[dp53]] -// CHECK-LL-NEXT: [[tmp55:%.*]] = load %class.test1_D** [[dp53]] -// CHECK-LL-NEXT: [[cmp56:%.*]] = icmp eq %class.test1_D* [[tmp55]], null -// CHECK-LL-NEXT: br i1 [[cmp56]], label %[[ifthen57:.*]], label %[[ifelse59:.*]] -// CHECK-LL: [[ifthen57]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 7) -// CHECK-LL-NEXT: br label %[[ifend61:.*]] -// CHECK-LL: [[ifelse59]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 7) -// CHECK-LL-NEXT: br label %[[ifend61]] -// CHECK-LL: [[ifend61]] -// CHECK-LL-NEXT: [[tmp63:%.*]] = load %class.test1_A** [[ap37]] -// CHECK-LL-NEXT: [[v42:%.*]] = icmp ne %class.test1_A* [[tmp63]], null -// CHECK-LL-NEXT: br i1 [[v42]], label %[[v43:.*]], label %[[v47:.*]] -// CHECK-LL: [[v44:%.*]] = bitcast %class.test1_A* [[tmp63]] to i8* -// CHECK-LL-NEXT: [[v45:%.*]] = call i8* @__dynamic_cast(i8* [[v44]], i8* bitcast ({{.*}} @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_E to i8*), i64 -1) -// CHECK-LL-NEXT: [[v46:%.*]] = bitcast i8* [[v45]] to %class.test1_E* -// CHECK-LL-NEXT: br label %[[v48:.*]] -// CHECK-LL: br label %[[v48]] -// CHECK-LL: [[v49:%.*]] = phi %class.test1_E* [ [[v46]], %[[v43]] ], [ null, %[[v47]] ] -// CHECK-LL-NEXT: store %class.test1_E* [[v49]], %class.test1_E** [[ep1]] -// CHECK-LL-NEXT: [[tmp64:%.*]] = load %class.test1_E** [[ep1]] -// CHECK-LL-NEXT: [[cmp65:%.*]] = icmp ne %class.test1_E* [[tmp64]], null -// CHECK-LL-NEXT: br i1 [[cmp65]], label %[[ifthen66:.*]], label %[[ifelse68:.*]] -// CHECK-LL: [[ifthen66]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 8) -// CHECK-LL-NEXT: br label %[[ifend70:.*]] -// CHECK-LL: [[ifelse68]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 8) -// CHECK-LL-NEXT: br label %[[ifend70]] -// CHECK-LL: [[ifend70]] -// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[tmp71:%.*]] = load %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[cmp72:%.*]] = icmp eq %class.test1_D* [[tmp71]], @test1_d -// CHECK-LL-NEXT: br i1 [[cmp72]], label %[[ifthen73:.*]], label %[[ifelse75:.*]] -// CHECK-LL: [[ifthen73]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 9) -// CHECK-LL-NEXT: br label %[[ifend77:.*]] -// CHECK-LL: [[ifelse75]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 9) -// CHECK-LL-NEXT: br label %[[ifend77]] -// CHECK-LL: [[ifend77]] -// CHECK-LL-NEXT: store %class.test1_D* @test1_d, %class.test1_D** [[cdp]] -// CHECK-LL-NEXT: [[tmp79:%.*]] = load %class.test1_D** [[cdp]] -// CHECK-LL-NEXT: [[cmp80:%.*]] = icmp eq %class.test1_D* [[tmp79]], @test1_d -// CHECK-LL-NEXT: br i1 [[cmp80]], label %[[ifthen81:.*]], label %[[ifelse83:.*]] -// CHECK-LL: [[ifthen81]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 10) -// CHECK-LL-NEXT: br label %[[ifend85:.*]] -// CHECK-LL: [[ifelse83]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 10) -// CHECK-LL-NEXT: br label %[[ifend85]] -// CHECK-LL: [[ifend85]] -// CHECK-LL-NEXT: br i1 false, label %[[v50:.*]], label %[[v53:.*]] -// CHECK-LL: [[v51:%.*]] = call i8* @__dynamic_cast(i8* null, i8* bitcast ({{.*}}* @_ZTI7test1_A to i8*), i8* bitcast ({{.*}} @_ZTI7test1_D to i8*), i64 -1) -// CHECK-LL-NEXT: [[v52:%.*]] = bitcast i8* [[v51]] to %class.test1_D* -// CHECK-LL-NEXT: br label %[[v54:.*]] -// CHECK-LL: br label %[[v54]] -// CHECK-LL: [[v55:%.*]] = phi %class.test1_D* [ [[v52]], %[[v50]] ], [ null, %[[v53]] ] -// CHECK-LL-NEXT: store %class.test1_D* [[v55]], %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[tmp86:%.*]] = load %class.test1_D** [[dp]] -// CHECK-LL-NEXT: [[cmp87:%.*]] = icmp eq %class.test1_D* [[tmp86]], null -// CHECK-LL-NEXT: br i1 [[cmp87]], label %[[ifthen88:.*]], label %[[ifelse90:.*]] -// CHECK-LL: [[ifthen88]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 11) -// CHECK-LL-NEXT: br label %[[ifend92:.*]] -// CHECK-LL: [[ifelse90]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 11) -// CHECK-LL-NEXT: br label %[[ifend92]] -// CHECK-LL: [[ifend92]] -// CHECK-LL-NEXT: br i1 false, label %[[castnull98:.*]], label %[[castnotnull93:.*]] -// CHECK-LL: [[castnotnull93]] -// CHECK-LL-NEXT: [[vtable94:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: [[vbaseoffsetptr95:%.*]] = getelementptr i8* [[vtable94]], i64 -24 -// CHECK-LL-NEXT: [[v56:%.*]] = bitcast i8* [[vbaseoffsetptr95]] to i64* -// CHECK-LL-NEXT: [[vbaseoffset96:%.*]] = load i64* [[v56]] -// CHECK-LL-NEXT: [[addptr97:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset96]] -// CHECK-LL-NEXT: [[v57:%.*]] = bitcast i8* [[addptr97]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[castend99:.*]] -// CHECK-LL: [[castnull98]] -// CHECK-LL-NEXT: br label %[[castend99]] -// CHECK-LL: [[castend99]] -// CHECK-LL-NEXT: [[v58:%.*]] = phi %class.test1_A* [ [[v57]], %[[castnotnull93]] ], [ null, %[[castnull98]] ] -// CHECK-LL-NEXT: store %class.test1_A* [[v58]], %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[tmp100:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: br i1 false, label %[[castnull106:.*]], label %[[castnotnull101:.*]] -// CHECK-LL: [[castnotnull101]] -// CHECK-LL-NEXT: [[vtable102:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: [[vbaseoffsetptr103:%.*]] = getelementptr i8* [[vtable102]], i64 -24 -// CHECK-LL-NEXT: [[v59:%.*]] = bitcast i8* [[vbaseoffsetptr103]] to i64* -// CHECK-LL-NEXT: [[vbaseoffset104:%.*]] = load i64* [[v59]] -// CHECK-LL-NEXT: [[addptr105:%.*]] = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 [[vbaseoffset104]] -// CHECK-LL-NEXT: [[v60:%.*]] = bitcast i8* [[addptr105]] to %class.test1_A* -// CHECK-LL-NEXT: br label %[[castend107:.*]] -// CHECK-LL: [[castnull106]] -// CHECK-LL-NEXT: br label %[[castend107]] -// CHECK-LL: [[castend107]] -// CHECK-LL-NEXT: [[v61:%.*]] = phi %class.test1_A* [ [[v60]], %[[castnotnull101]] ], [ null, %[[castnull106]] ] -// CHECK-LL-NEXT: [[cmp108:%.*]] = icmp eq %class.test1_A* [[tmp100]], [[v61]] -// CHECK-LL-NEXT: br i1 [[cmp108]], label %[[ifthen109:.*]], label %[[ifelse111:.*]] -// CHECK-LL: [[ifthen109]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 12) -// CHECK-LL-NEXT: br label %[[ifend113:.*]] -// CHECK-LL: [[ifelse111]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 12) -// CHECK-LL-NEXT: br label %[[ifend113]] -// CHECK-LL: [[ifend113]] -// CHECK-LL-NEXT: store %class.test1_E* bitcast (%class.test1_F* @test1_f to %class.test1_E*), %class.test1_E** [[ep]] -// CHECK-LL-NEXT: [[tmp118:%.*]] = load %class.test1_E** [[ep]] -// CHECK-LL-NEXT: [[cmp122:%.*]] = icmp eq %class.test1_E* [[tmp118]], bitcast (%class.test1_F* @test1_f to %class.test1_E*) - -// CHECK-LL-NEXT: br i1 [[cmp122]], label %[[ifthen123:.*]], label %[[ifelse125:.*]] -// CHECK-LL: [[ifthen123]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 13) -// CHECK-LL-NEXT: br label %[[ifend127:.*]] -// CHECK-LL: [[ifelse125]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 13) -// CHECK-LL-NEXT: br label %[[ifend127]] -// CHECK-LL: [[ifend127]] -// CHECK-LL-NEXT: [[tmp129:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[v64:%.*]] = icmp ne %class.test1_A* [[tmp129]], null -// CHECK-LL-NEXT: br i1 [[v64]], label %[[v65:.*]], label %[[v70:.*]] -// CHECK-LL: [[v66:%.*]] = bitcast %class.test1_A* [[tmp129]] to i64** -// CHECK-LL-NEXT: [[vtable130:%.*]] = load i64** [[v66]] -// CHECK-LL-NEXT: [[v67:%.*]] = getelementptr inbounds i64* [[vtable130]], i64 -2 -// CHECK-LL-NEXT: [[offsettotop:%.*]] = load i64* [[v67]] -// CHECK-LL-NEXT: [[v68:%.*]] = bitcast %class.test1_A* [[tmp129]] to i8* -// CHECK-LL-NEXT: [[v69:%.*]] = getelementptr inbounds i8* [[v68]], i64 [[offsettotop]] -// CHECK-LL-NEXT: br label %[[v71:.*]] -// CHECK-LL: br label %[[v71]] -// CHECK-LL: [[v72:%.*]] = phi i8* [ [[v69]], %[[v65]] ], [ null, %[[v70]] ] -// CHECK-LL-NEXT: store i8* [[v72]], i8** [[vp]] -// CHECK-LL-NEXT: [[tmp131:%.*]] = load i8** [[vp]] -// CHECK-LL-NEXT: [[cmp132:%.*]] = icmp eq i8* [[tmp131]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) -// CHECK-LL-NEXT: br i1 [[cmp132]], label %[[ifthen133:.*]], label %[[ifelse135:.*]] -// CHECK-LL: [[ifthen133]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 14) -// CHECK-LL-NEXT: br label %[[ifend137:.*]] -// CHECK-LL: [[ifelse135]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 14) -// CHECK-LL-NEXT: br label %[[ifend137]] -// CHECK-LL: [[ifend137]] -// CHECK-LL-NEXT: [[tmp139:%.*]] = load %class.test1_A** [[ap]] -// CHECK-LL-NEXT: [[v73:%.*]] = icmp ne %class.test1_A* [[tmp139]], null -// CHECK-LL-NEXT: br i1 [[v73]], label %[[v74:.*]], label %[[v79:.*]] -// CHECK-LL: [[v75:%.*]] = bitcast %class.test1_A* [[tmp139]] to i64** -// CHECK-LL-NEXT: [[vtable140:%.*]] = load i64** [[v75]] -// CHECK-LL-NEXT: [[v76:%.*]] = getelementptr inbounds i64* [[vtable140]], i64 -2 -// CHECK-LL-NEXT: [[offsettotop141:%.*]] = load i64* [[v76]] -// CHECK-LL-NEXT: [[v77:%.*]] = bitcast %class.test1_A* [[tmp139]] to i8* -// CHECK-LL-NEXT: [[v78:%.*]] = getelementptr inbounds i8* [[v77]], i64 [[offsettotop141]] -// CHECK-LL-NEXT: br label %[[v80:.*]] -// CHECK-LL: br label %[[v80]] -// CHECK-LL: [[v81:%.*]] = phi i8* [ [[v78]], %[[v74]] ], [ null, %[[v79]] ] -// CHECK-LL-NEXT: store i8* [[v81]], i8** [[cvp]] -// CHECK-LL-NEXT: [[tmp142:%.*]] = load i8** [[cvp]] -// CHECK-LL-NEXT: [[cmp143:%.*]] = icmp eq i8* [[tmp142]], getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0) -// CHECK-LL-NEXT: br i1 [[cmp143]], label %[[ifthen144:.*]], label %[[ifelse146:.*]] -// CHECK-LL: [[ifthen144]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 15) -// CHECK-LL-NEXT: br label %[[ifend148:.*]] -// CHECK-LL: [[ifelse146]] -// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 15) -// CHECK-LL-NEXT: br label %[[ifend148]] -// CHECK-LL: [[ifend148]] -// CHECK-LL-NEXT: ret void diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 5ae65cc..6c44c76 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s struct test1_D { diff --git a/test/CodeGenCXX/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp index bbbc1b8..902d6ac 100644 --- a/test/CodeGenCXX/exceptions-no-rtti.cpp +++ b/test/CodeGenCXX/exceptions-no-rtti.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -fno-rtti -fcxx-exceptions -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s // CHECK: @_ZTIN5test11AE = linkonce_odr unnamed_addr constant // CHECK: @_ZTIN5test11BE = linkonce_odr unnamed_addr constant diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index 8081818..d9b8506 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s typedef typeof(sizeof(0)) size_t; @@ -305,3 +305,88 @@ namespace test6 { } } } + +// PR9298 +namespace test7 { + struct A { A(); ~A(); }; + struct B { + // The throw() operator means that a bad allocation is signalled + // with a null return, which means that the initializer is + // evaluated conditionally. + static void *operator new(size_t size) throw(); + B(const A&, B*); + ~B(); + }; + + B *test() { + // CHECK: define [[B:%.*]]* @_ZN5test74testEv() + // CHECK: [[OUTER_NEW:%.*]] = alloca i1 + // CHECK-NEXT: alloca [[A:%.*]], + // CHECK-NEXT: alloca i8* + // CHECK-NEXT: alloca i32 + // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1 + // CHECK-NEXT: alloca i8* + // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1 + // CHECK-NEXT: alloca [[A]] + // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1 + + // These entry-block stores are to deactivate the delete cleanups. + // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]] + // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]] + + // Allocate the outer object. + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( + // CHECK-NEXT: icmp eq i8* [[NEW]], null + + // These stores, emitted before the outermost conditional branch, + // deactivate the temporary cleanups. + // CHECK-NEXT: store i1 false, i1* [[OUTER_A]] + // CHECK-NEXT: store i1 false, i1* [[INNER_A]] + // CHECK-NEXT: br i1 + + // We passed the first null check; activate that cleanup and continue. + // CHECK: store i1 true, i1* [[OUTER_NEW]] + // CHECK-NEXT: bitcast + + // Create the first A temporary and activate that cleanup. + // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( + // CHECK: store i1 true, i1* [[OUTER_A]] + + // Allocate the inner object. + // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( + // CHECK-NEXT: icmp eq i8* [[NEW]], null + // CHECK-NEXT: br i1 + + // We passed the second null check; save that pointer, activate + // that cleanup, and continue. + // CHECK: store i8* [[NEW]] + // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]] + // CHECK-NEXT: bitcast + + // Build the second A temporary and activate that cleanup. + // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( + // CHECK: store i1 true, i1* [[INNER_A]] + + // Build the inner B object and deactivate the inner delete cleanup. + // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( + // CHECK: store i1 false, i1* [[INNER_NEW]] + // CHECK: phi + + // Build the outer B object and deactivate the outer delete cleanup. + // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( + // CHECK: store i1 false, i1* [[OUTER_NEW]] + // CHECK: phi + + // Destroy the inner A object. + // CHECK-NEXT: load i1* [[INNER_A]] + // CHECK-NEXT: br i1 + // CHECK: invoke void @_ZN5test71AD1Ev( + + // Destroy the outer A object. + // CHECK: load i1* [[OUTER_A]] + // CHECK-NEXT: br i1 + // CHECK: invoke void @_ZN5test71AD1Ev( + + return new B(A(), new B(A(), 0)); + } +} diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp index b829585..8daf3c6 100644 --- a/test/CodeGenCXX/explicit-instantiation.cpp +++ b/test/CodeGenCXX/explicit-instantiation.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s // This check logically is attached to 'template int S<int>::i;' below. -// CHECK: @_ZN1SIiE1iE = weak global i32 +// CHECK: @_ZN1SIiE1iE = weak_odr global i32 template<typename T, typename U, typename Result> struct plus { diff --git a/test/CodeGenCXX/for-range-temporaries.cpp b/test/CodeGenCXX/for-range-temporaries.cpp new file mode 100644 index 0000000..be594ce --- /dev/null +++ b/test/CodeGenCXX/for-range-temporaries.cpp @@ -0,0 +1,131 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - -UDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - -DDESUGAR %s | opt -instnamer -S | FileCheck %s + +struct A { + A(); + A(const A &); + ~A(); +}; + +struct B { + B(); + B(const B &); + ~B(); +}; + +struct C { + C(const B &); + C(const C &); + ~C(); +}; + +struct E; +struct D { + D(const C &); + D(const D &); + ~D(); +}; +E begin(D); +E end(D); + +struct F; +struct G; +struct H; +struct E { + E(const E &); + ~E(); + F operator*(); + G operator++(); + H operator!=(const E &o); +}; + +struct I; +struct F { + F(const F &); + ~F(); + operator I(); +}; + +struct G { + G(const G &); + ~G(); + operator bool(); +}; + +struct H { + H(const H &); + ~H(); + operator bool(); +}; + +struct I { + I(const I &); + ~I(); +}; + +void body(const I &); + +void for_temps() { + A a; +#ifdef DESUGAR + { + auto && __range = D(B()); + for (auto __begin = begin(__range), __end = end(__range); + __begin != __end; ++__begin) { + I i = *__begin; + body(i); + } + } +#else + for (I i : D(B())) { + body(i); + } +#endif +} + +// CHECK: define void @_Z9for_tempsv() +// CHECK: call void @_ZN1AC1Ev( +// CHECK: call void @_ZN1BC1Ev( +// CHECK: call void @_ZN1CC1ERK1B( +// CHECK: call void @_ZN1DC1ERK1C( +// CHECK: call void @_ZN1CD1Ev( +// CHECK: call void @_ZN1BD1Ev( +// CHECK: call void @_ZN1DC1ERKS_( +// CHECK: call void @_Z5begin1D( +// CHECK: call void @_ZN1DD1Ev( +// CHECK: call void @_ZN1DC1ERKS_( +// CHECK: call void @_Z3end1D( +// CHECK: call void @_ZN1DD1Ev( +// CHECK: br label %[[COND:.*]] + +// CHECK: [[COND]]: +// CHECK: call void @_ZN1EneERKS_( +// CHECK: %[[CMP:.*]] = call zeroext i1 @_ZN1HcvbEv( +// CHECK: call void @_ZN1HD1Ev( +// CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + +// CHECK: [[CLEANUP]]: +// CHECK: call void @_ZN1ED1Ev( +// CHECK: call void @_ZN1ED1Ev( +// In for-range: +// call void @_ZN1DD1Ev( +// CHECK: br label %[[END:.*]] + +// CHECK: [[BODY]]: +// CHECK: call void @_ZN1EdeEv( +// CHECK: call void @_ZN1Fcv1IEv( +// CHECK: call void @_ZN1FD1Ev( +// CHECK: call void @_Z4bodyRK1I( +// CHECK: call void @_ZN1ID1Ev( +// CHECK: br label %[[INC:.*]] + +// CHECK: [[INC]]: +// CHECK: call void @_ZN1EppEv( +// CHECK: call void @_ZN1GD1Ev( +// CHECK: br label %[[COND]] + +// CHECK: [[END]]: +// In desugared version: +// call void @_ZN1DD1Ev( +// CHECK: call void @_ZN1AD1Ev( +// CHECK: ret void diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp new file mode 100644 index 0000000..af46644 --- /dev/null +++ b/test/CodeGenCXX/for-range.cpp @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - %s | opt -instnamer -S | FileCheck %s + +struct A { + A(); + A(const A&); + ~A(); +}; + +struct B { + B(); + B(const B&); + ~B(); +}; + +struct C { + C(); + C(const C&); + ~C(); +}; + +struct D { + D(); + D(const D&); + ~D(); + + B *begin(); + B *end(); +}; + +namespace std { + B *begin(C&); + B *end(C&); +} + +extern B array[5]; + +// CHECK: define void @_Z9for_arrayv( +void for_array() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : array) { + // CHECK-NOT: 5begin + // CHECK-NOT: 3end + // CHECK: getelementptr {{.*}}, i32 0 + // CHECK: getelementptr {{.*}}, i64 5 + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} + +// CHECK: define void @_Z9for_rangev( +void for_range() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : C()) { + // CHECK: call void @_ZN1CC1Ev( + // CHECK: = call %struct.A* @_ZSt5beginR1C( + // CHECK: = call %struct.A* @_ZSt3endR1C( + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + + // CHECK: [[CLEANUP]]: + // CHECK: call void @_ZN1CD1Ev( + // CHECK: br label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} + +// CHECK: define void @_Z16for_member_rangev( +void for_member_range() { + // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]]) + A a; + for (B b : D()) { + // CHECK: call void @_ZN1DC1Ev( + // CHECK: = call %struct.A* @_ZN1D5beginEv( + // CHECK: = call %struct.A* @_ZN1D3endEv( + // CHECK: br label %[[COND:.*]] + + // CHECK: [[COND]]: + // CHECK: %[[CMP:.*]] = icmp ne + // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]] + + // CHECK: [[CLEANUP]]: + // CHECK: call void @_ZN1DD1Ev( + // CHECK: br label %[[END:.*]] + + // CHECK: [[BODY]]: + // CHECK: call void @_ZN1BC1ERKS_( + // CHECK: call void @_ZN1BD1Ev( + // CHECK: br label %[[INC:.*]] + + // CHECK: [[INC]]: + // CHECK: getelementptr {{.*}} i32 1 + // CHECK: br label %[[COND]] + } + // CHECK: [[END]]: + // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]]) + // CHECK: ret void +} diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp index 6003270..9bd7390 100644 --- a/test/CodeGenCXX/global-init.cpp +++ b/test/CodeGenCXX/global-init.cpp @@ -20,8 +20,8 @@ struct D { ~D(); }; // PR6205: The casts should not require global initializers // CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C" -// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to %"struct.PR5974::A"*), align 8 -// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0, i64 4) to %"struct.PR5974::A"*), align 8 +// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0) +// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::A"*), align 8 // CHECK: call void @_ZN1AC1Ev(%struct.A* @a) // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) @@ -90,6 +90,23 @@ namespace PR5974 { // CHECK-NEXT: sub // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE +// PR9570: the indirect field shouldn't crash IR gen. +namespace test5 { + static union { + unsigned bar[4096] __attribute__((aligned(128))); + }; +} + +namespace test6 { + struct A { + A(); + }; + extern int foo(); + + // This needs an initialization function but not guard variables. + __attribute__((weak)) int x = foo(); +} + // At the end of the file, we check that y is initialized before z. // CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" { diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp index 938d4e1..3286b22 100644 --- a/test/CodeGenCXX/goto.cpp +++ b/test/CodeGenCXX/goto.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fexceptions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -o - | FileCheck %s // Reduced from a crash on boost::interprocess's node_allocator_test.cpp. namespace test0 { diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index e5f26e5..46c46f0 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -49,3 +49,63 @@ namespace Casts { // CHECK: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE( template void auto_<int>(int*); } + +namespace test1 { + short foo(short); + int foo(int); + + // CHECK: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_( + template <class T> auto a(T t) -> decltype(foo(T())) { return foo(t); } + + // CHECK: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_( + template <class T> auto b(T t) -> decltype((foo)(T())) { return (foo)(t); } + + void test(short s) { + a(s); + b(s); + } +} + +namespace test2 { + template <class T> void a(T x, decltype(x()) y) {} + template <class T> auto b(T x) -> decltype(x()) { return x(); } + template <class T> void c(T x, void (*p)(decltype(x()))) {} + template <class T> void d(T x, auto (*p)() -> decltype(x())) {} + template <class T> void e(auto (*p)(T y) -> decltype(y())) {} + template <class T> void f(void (*p)(T x, decltype(x()) y)) {} + template <class T> void g(T x, decltype(x()) y) { + static decltype(x()) variable; + variable = 0; + } + template <class T> void h(T x, decltype((decltype(x())(*)()) 0) y) {} + template <class T> void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {} + + float foo(); + void bar(float); + float baz(float(*)()); + void fred(float(*)(), float); + + // CHECK: define void @_ZN5test211instantiateEv + void instantiate() { + // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE( + a(foo, 0.0f); + // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_( + (void) b(foo); + // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE( + c(foo, bar); + // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE( + d(foo, foo); + // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E( + e(baz); + // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE( + f(fred); + // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE( + g(foo, 0.0f); + // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE( + h(foo, foo); + // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE( + i<float(*)()>(baz); + } + + // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable, +} diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index 8d79988..fea3582 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -5,8 +5,8 @@ // CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant -// CHECK: @_ZTCSd0_Si = internal constant -// CHECK: @_ZTCSd16_So = internal constant +// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant +// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index ec496fe..27777a5 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -183,7 +183,7 @@ template <typename T> typename T::U ft6(const T&) { return 0; } // CHECK: @_Z3ft6I1SENT_1UERKS1_ template int ft6<S>(const S&); -template<typename> struct __is_scalar { +template<typename> struct __is_scalar_type { enum { __value = 1 }; }; @@ -194,11 +194,11 @@ template<typename T> struct __enable_if<true, T> { }; // PR5063 -template<typename T> typename __enable_if<__is_scalar<T>::__value, void>::__type ft7() { } +template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { } -// CHECK: @_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv template void ft7<int>(); -// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv template void ft7<void*>(); // PR5144 @@ -225,15 +225,15 @@ struct S7 { S7::S7() {} // PR5063 -template<typename T> typename __enable_if<(__is_scalar<T>::__value), void>::__type ft8() { } -// CHECK: @_Z3ft8IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { } +// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv template void ft8<int>(); -// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv +// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv template void ft8<void*>(); // PR5796 namespace PR5796 { -template<typename> struct __is_scalar { +template<typename> struct __is_scalar_type { enum { __value = 0 }; }; @@ -241,8 +241,8 @@ template<bool, typename> struct __enable_if {}; template<typename T> struct __enable_if<true, T> { typedef T __type; }; template<typename T> -// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_11__is_scalarIT_EE7__valueEvE6__typeEv -typename __enable_if<!__is_scalar<T>::__value, void>::__type __fill_a() { }; +// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_16__is_scalar_typeIT_EE7__valueEvE6__typeEv +typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { }; void f() { __fill_a<int>(); } } @@ -348,7 +348,7 @@ namespace test0 { char buffer[sizeof(float)]; g<float>(buffer); } - // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40A00000E_c( + // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c( template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {} void test3() { @@ -373,7 +373,7 @@ namespace test1 { template void f(X<int>); } -// CHECK: define internal void @_Z27functionWithInternalLinkagev() +// CHECK: define internal void @_ZL27functionWithInternalLinkagev() static void functionWithInternalLinkage() { } void g() { functionWithInternalLinkage(); } @@ -390,26 +390,29 @@ namespace test2 { // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_( } +// rdar://problem/9280586 namespace test3 { struct AmbiguousBase { int ab; }; struct Path1 : AmbiguousBase { float p; }; struct Path2 : AmbiguousBase { double p; }; struct Derived : Path1, Path2 { }; - //template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; } - //template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; } + // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path1E2abERS2_( + template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; } - // define weak_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_( + // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path2E2abERS2_( + template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; } + + // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path1E1pERS2_( template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; } - // define weak_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_( + // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path2E1pERS2_( template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; } Derived obj; void test() { - // FIXME: uncomment these when we support diamonds competently - //get_ab_1(obj); - //get_ab_2(obj); + get_ab_1(obj); + get_ab_2(obj); get_p_1(obj); get_p_2(obj); } @@ -647,3 +650,29 @@ namespace test23 { void f(vpca5 volatile (&)[10]) {} // CHECK: define void @_ZN6test231fERA10_A5_VKPv( } + +namespace test24 { + void test0() { + extern int foo(); + // CHECK: call i32 @_ZN6test243fooEv() + foo(); + } + + static char foo() {} + void test1() { + // CHECK: call signext i8 @_ZN6test24L3fooEv() + foo(); + } +} + +// rdar://problem/8806641 +namespace test25 { + template <void (*fn)()> struct A { + static void call() { fn(); } + }; + void foo(); + void test() { + // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv() + A<foo>::call(); + } +} diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 78a571e..011e9cd 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -209,3 +209,26 @@ namespace test8 { return pmf(); } } + +namespace test9 { + struct A { + void foo(); + }; + struct B : A { + void foo(); + }; + + typedef void (A::*fooptr)(); + + struct S { + fooptr p; + }; + + // CHECK: define void @_ZN5test94testEv( + // CHECK: alloca i32 + // CHECK-NEXT: ret void + void test() { + int x; + static S array[] = { (fooptr) &B::foo }; + } +} diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index d03b21bac..ad6fa4f 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -O1 -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s +// RUN: %clang_cc1 -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s // Test code generation for the named return value optimization. class X { diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp index 40723a8..2a22d23 100644 --- a/test/CodeGenCXX/pointers-to-data-members.cpp +++ b/test/CodeGenCXX/pointers-to-data-members.cpp @@ -55,7 +55,7 @@ namespace ZeroInit { }; struct C : A, B { int j; }; - // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { [16 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00", [176 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i32 0, [4 x i8] zeroinitializer } + // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.PR7139::ptr_to_member_struct"] [%"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }, %"struct.PR7139::ptr_to_member_struct" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0 }, align 8 C c; } @@ -172,15 +172,15 @@ struct A { int A::*i; }; -// CHECK-GLOBAL: @_ZN12VirtualBases1bE = global {{%.*}} { i32 (...)** null, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" } +// CHECK-GLOBAL: @_ZN12VirtualBases1bE = global %"struct.VirtualBases::B" { i32 (...)** null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 struct B : virtual A { }; B b; -// CHECK-GLOBAL: @_ZN12VirtualBases1cE = global {{%.*}} { i32 (...)** null, i64 -1, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" } +// CHECK-GLOBAL: @_ZN12VirtualBases1cE = global %"struct.VirtualBases::C" { i32 (...)** null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 struct C : virtual A { int A::*i; }; C c; - // CHECK-GLOBAL: @_ZN12VirtualBases1dE = global {{%.*}} { [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i64 -1, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" } +// CHECK-GLOBAL: @_ZN12VirtualBases1dE = global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 struct D : C { int A::*i; }; D d; @@ -227,6 +227,6 @@ namespace test4 { struct C : virtual B { int *C_p; }; struct D : C { int *D_p; }; - // CHECK-GLOBAL: @_ZN5test41dE = global {{%.*}} { [16 x i8] zeroinitializer, i32* null, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", [4 x i8] zeroinitializer } + // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8 D d; } diff --git a/test/CodeGenCXX/pragma-pack.cpp b/test/CodeGenCXX/pragma-pack.cpp index c0ddb1d..c0b0259 100644 --- a/test/CodeGenCXX/pragma-pack.cpp +++ b/test/CodeGenCXX/pragma-pack.cpp @@ -10,5 +10,7 @@ struct Sub : virtual Base { char c; }; -// CHECK: %struct.Sub = type <{ i32 (...)**, i8, [8 x i8] }> +// CHECK: %struct.Sub = type <{ i32 (...)**, i8, %struct.Base }> void f(Sub*) { } + +static int i[sizeof(Sub) == 13 ? 1 : -1]; diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index d2ad9801..25bc8d8 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -258,3 +258,14 @@ void f() { } } +// PR9494 +namespace N5 { +struct AnyS { bool b; }; +void f(const bool&); +AnyS g(); +void h() { + // CHECK: call i8 @_ZN2N51gEv() + // CHECK: call void @_ZN2N51fERKb(i8* + f(g().b); +} +} diff --git a/test/CodeGenCXX/specialized-static-data-mem-init.cpp b/test/CodeGenCXX/specialized-static-data-mem-init.cpp index 8f5765b..c2a2ddb 100644 --- a/test/CodeGenCXX/specialized-static-data-mem-init.cpp +++ b/test/CodeGenCXX/specialized-static-data-mem-init.cpp @@ -2,8 +2,8 @@ // rdar: // 8562966 // pr8409 -// CHECK: @_ZN1CIiE11needs_guardE = weak global -// CHECK: @_ZGVN1CIiE11needs_guardE = weak global +// CHECK: @_ZN1CIiE11needs_guardE = weak_odr global +// CHECK: @_ZGVN1CIiE11needs_guardE = weak_odr global struct K { diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp index 64fca2e..b19067a 100644 --- a/test/CodeGenCXX/static-data-member.cpp +++ b/test/CodeGenCXX/static-data-member.cpp @@ -2,8 +2,8 @@ // CHECK: @_ZN5test11A1aE = constant i32 10, align 4 // CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4 -// CHECK: @_ZN5test31AIiE1xE = weak global i32 0, align 4 -// CHECK: @_ZGVN5test31AIiE1xE = weak global i64 0 +// CHECK: @_ZN5test31AIiE1xE = weak_odr global i32 0, align 4 +// CHECK: @_ZGVN5test31AIiE1xE = weak_odr global i64 0 // PR5564. namespace test1 { diff --git a/test/CodeGenCXX/static-init-3.cpp b/test/CodeGenCXX/static-init-3.cpp index 5bf76a6..bd717ca 100644 --- a/test/CodeGenCXX/static-init-3.cpp +++ b/test/CodeGenCXX/static-init-3.cpp @@ -16,8 +16,8 @@ struct X1 } }; -// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak global %struct.X0* null, align 8 -// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak global %struct.X0* null, align 8 +// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak_odr global %struct.X0* null, align 8 +// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak_odr global %struct.X0* null, align 8 template<class T> T & X1<T>::instance = X1<T>::get(); class A { }; diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index dd9ed61..78749a7 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -2,7 +2,7 @@ // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4 -// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 +// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0 @@ -50,7 +50,7 @@ namespace test0 { } namespace test1 { - // CHECK: define internal i32 @_ZN5test16getvarEi( + // CHECK: define internal i32 @_ZN5test1L6getvarEi( static inline int getvar(int index) { static const int var[] = { 1, 0, 2, 4 }; return var[index]; diff --git a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp index ca4446c..2c62b60 100644 --- a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp +++ b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fvisibility hidden -emit-llvm -o - %s | FileCheck %s // Verify that symbols are hidden. -// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak hidden global +// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak_odr hidden global // CHECK: define weak_odr hidden void @_ZN1CIiE5Inner1fEv // CHECK: define weak_odr hidden void @_ZN1CIiE5Inner6Inner21gEv diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp index 87be572..0bd810e 100644 --- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp +++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - -fexceptions -triple x86_64-apple-darwin10 %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 %s | FileCheck %s struct X { X(); diff --git a/test/CodeGenCXX/threadsafe-statics.cpp b/test/CodeGenCXX/threadsafe-statics.cpp index 65ebc43..8afc274 100644 --- a/test/CodeGenCXX/threadsafe-statics.cpp +++ b/test/CodeGenCXX/threadsafe-statics.cpp @@ -1,8 +1,11 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=WITH-TSS %s -// RUN: %clang_cc1 -emit-llvm -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s +// RUN: %clang_cc1 -emit-llvm -triple=x86_64-apple-darwin10 -o - %s | FileCheck -check-prefix=WITH-TSS %s +// RUN: %clang_cc1 -emit-llvm -triple=x86_64-apple-darwin10 -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s int f(); +// WITH-TSS: @_ZZ1gvE1a = internal global i32 0, align 4 +// WITH-TSS: @_ZGVZ1gvE1a = internal global i64 0 + // WITH-TSS: define void @_Z1gv() nounwind // WITH-TSS: call i32 @__cxa_guard_acquire // WITH-TSS: call void @__cxa_guard_release @@ -11,6 +14,9 @@ void g() { static int a = f(); } +// NO-TSS: @_ZZ1gvE1a = internal global i32 0, align 4 +// NO-TSS: @_ZGVZ1gvE1a = internal global i8 0 + // NO-TSS: define void @_Z1gv() nounwind // NO-TSS-NOT: call i32 @__cxa_guard_acquire // NO-TSS-NOT: call void @__cxa_guard_release diff --git a/test/CodeGenCXX/throw-expression-dtor.cpp b/test/CodeGenCXX/throw-expression-dtor.cpp index f87657f..0de6683 100644 --- a/test/CodeGenCXX/throw-expression-dtor.cpp +++ b/test/CodeGenCXX/throw-expression-dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm-only -verify -fexceptions +// RUN: %clang_cc1 %s -emit-llvm-only -verify -fcxx-exceptions -fexceptions // PR7281 class A { diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp index 1d22ec0..0fd32c4 100644 --- a/test/CodeGenCXX/throw-expressions.cpp +++ b/test/CodeGenCXX/throw-expressions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code int val = 42; int& test1() { diff --git a/test/CodeGenCXX/try-catch.cpp b/test/CodeGenCXX/try-catch.cpp index 2b5f323..89f229f 100644 --- a/test/CodeGenCXX/try-catch.cpp +++ b/test/CodeGenCXX/try-catch.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s struct X { }; diff --git a/test/CodeGenCXX/typeid.cpp b/test/CodeGenCXX/typeid.cpp new file mode 100644 index 0000000..1af9670 --- /dev/null +++ b/test/CodeGenCXX/typeid.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s +#include <typeinfo> + +namespace Test1 { + +// PR7400 +struct A { virtual void f(); }; + +// CHECK: define i8* @_ZN5Test11fEv +const char *f() { + try { + // CHECK: br i1 + // CHECK: invoke void @__cxa_bad_typeid() noreturn + return typeid(*static_cast<A *>(0)).name(); + } catch (...) { + // CHECK: call i8* @llvm.eh.exception + } + + return 0; +} + +} diff --git a/test/CodeGenCXX/unknown-anytype.cpp b/test/CodeGenCXX/unknown-anytype.cpp new file mode 100644 index 0000000..902cc8d --- /dev/null +++ b/test/CodeGenCXX/unknown-anytype.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -funknown-anytype -emit-llvm -o - %s | FileCheck %s + +int test0() { + extern __unknown_anytype test0_any; + // CHECK: load i32* @test0_any + return (int) test0_any; +} + +int test1() { + extern __unknown_anytype test1_any(); + // CHECK: call i32 @_Z9test1_anyv() + return (int) test1_any(); +} + +extern "C" __unknown_anytype test2_any(...); +float test2() { + // CHECK: call float (...)* @test2_any(double {{[^,]+}}) + return (float) test2_any(0.5f); +} + +extern "C" __unknown_anytype test2a_any(...); +float test2a() { + // CHECK: call float (...)* @test2a_any(float {{[^,]+}}) + return (float) test2a_any((float) 0.5f); +} + +float test3() { + extern __unknown_anytype test3_any; + // CHECK: [[FN:%.*]] = load float (i32)** @test3_any, + // CHECK: call float [[FN]](i32 5) + return ((float(*)(int)) test3_any)(5); +} + +namespace test4 { + extern __unknown_anytype test4_any1; + extern __unknown_anytype test4_any2; + + int test() { + // CHECK: load i32* @_ZN5test410test4_any1E + // CHECK: load i8* @_ZN5test410test4_any2E + return (int) test4_any1 + (char) test4_any2; + } +} + +extern "C" __unknown_anytype test5_any(); +void test5() { + // CHECK: call void @test5_any() + return (void) test5_any(); +} + +extern "C" __unknown_anytype test6_any(float *); +long test6() { + // CHECK: call i64 @test6_any(float* null) + return (long) test6_any(0); +} + +struct Test7 { + ~Test7(); +}; +extern "C" __unknown_anytype test7_any(int); +Test7 test7() { + // CHECK: call void @test7_any({{%.*}}* sret {{%.*}}, i32 5) + return (Test7) test7_any(5); +} + +struct Test8 { + __unknown_anytype foo(); + __unknown_anytype foo(int); + + void test(); +}; +void Test8::test() { + float f; + // CHECK: call i32 @_ZN5Test83fooEv( + f = (int) foo(); + // CHECK: call i32 @_ZN5Test83fooEi( + f = (int) foo(5); + // CHECK: call i32 @_ZN5Test83fooEv( + f = (float) this->foo(); + // CHECK: call i32 @_ZN5Test83fooEi( + f = (float) this->foo(5); +} +void test8(Test8 *p) { + double d; + // CHECK: call i32 @_ZN5Test83fooEv( + d = (double) p->foo(); + // CHECK: call i32 @_ZN5Test83fooEi( + d = (double) p->foo(5); + // CHECK: call i32 @_ZN5Test83fooEv( + d = (bool) (*p).foo(); + // CHECK: call i32 @_ZN5Test83fooEi( + d = (bool) (*p).foo(5); +} + +extern "C" __unknown_anytype test9_foo; +void *test9() { + // CHECK: ret i8* bitcast (i32* @test9_foo to i8*) + return (int*) &test9_foo; +} diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index 258d692..a5a0b67 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/test/CodeGenCXX/value-init.cpp @@ -83,6 +83,61 @@ namespace ptrmem { } } +namespace PR9801 { + +struct Test { + Test() : i(10) {} + Test(int i) : i(i) {} + int i; +private: + int j; +}; + +struct Test2 { + Test t; +}; + +struct Test3 : public Test { }; + +// CHECK: define void @_ZN6PR98011fEv +void f() { + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ei + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ev + Test partial[3] = { 1 }; + + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98014TestC1Ev + Test empty[3] = {}; + + // CHECK: call void @llvm.memset.p0i8.i64 + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test2C1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test2C1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test2C1Ev + Test2 empty2[3] = {}; + + // CHECK: call void @llvm.memset.p0i8.i64 + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test3C1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test3C1Ev + // CHECK-NOT: call void @llvm.memset.p0i8.i64 + // CHECK: call void @_ZN6PR98015Test3C1Ev + Test3 empty3[3] = {}; +} + +} + namespace zeroinit { struct S { int i; }; @@ -121,6 +176,7 @@ namespace zeroinit { template<typename> struct X3 : X2<int> { X3() : X2<int>() { } + int i; }; @@ -133,7 +189,7 @@ namespace zeroinit { X3<int>().f(); } - // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%struct.B* %this) unnamed_addr + // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr // CHECK: call void @llvm.memset.p0i8.i64 // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp index 9314650..7644e47 100644 --- a/test/CodeGenCXX/visibility.cpp +++ b/test/CodeGenCXX/visibility.cpp @@ -411,3 +411,14 @@ namespace Test20 { B<A<2> >::test5(); } } + +// PR9371 +namespace test21 { + enum En { en }; + template<En> struct A { + __attribute__((visibility("default"))) void foo() {} + }; + + // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( + template void A<en>::foo(); +} diff --git a/test/CodeGenCXX/vtable-debug-info.cpp b/test/CodeGenCXX/vtable-debug-info.cpp index c355406..9294d20 100644 --- a/test/CodeGenCXX/vtable-debug-info.cpp +++ b/test/CodeGenCXX/vtable-debug-info.cpp @@ -2,8 +2,9 @@ // Radar 8730409 // XFAIL: win32 -// FIXME: This test crashes on Windows. -#ifdef _WIN32 +// FIXME: This test crashes on *-pc-win32 +// for lack of debugging support on -integrated-as (MCCOFF). +#ifdef _MSC_VER #error this test must xfail diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 1cf8a52..bd69681 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -41,6 +41,7 @@ // RUN: FileCheck --check-prefix=CHECK-40 %s < %t // RUN: FileCheck --check-prefix=CHECK-41 %s < %t // RUN: FileCheck --check-prefix=CHECK-42 %s < %t +// RUN: FileCheck --check-prefix=CHECK-43 %s < %t // For now, just verify this doesn't crash. namespace test0 { @@ -1679,3 +1680,24 @@ struct D : virtual B, C { void D::g() { } } + +namespace Test37 { + +// Test that we give C::f the right vtable index. (PR9660). +struct A { + virtual A* f() = 0; +}; + +struct B : virtual A { + virtual B* f(); +}; + +// CHECK-43: VTable indices for 'Test37::C' (1 entries). +// CHECK-43-NEXT: 1 | Test37::C *Test37::C::f() +struct C : B { + virtual C* f(); +}; + +C* C::f() { return 0; } + +} diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index fc14c71..4633a3f 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -203,7 +203,7 @@ void G_f0() { new G<int>(); } // RUN: FileCheck --check-prefix=CHECK-H %s < %t // H<int> has a key function without a body but it's a template instantiation -// so its VTable must be emmitted. +// so its VTable must be emitted. // CHECK-H: @_ZTV1HIiE = linkonce_odr unnamed_addr constant template <typename T> class H { diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp index e731698..01f1a44 100644 --- a/test/CodeGenCXX/x86_64-arguments.cpp +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -3,13 +3,13 @@ // Basic base class test. struct f0_s0 { unsigned a; }; struct f0_s1 : public f0_s0 { void *b; }; -// CHECK: define void @_Z2f05f0_s1(i64 %a0.coerce0, i8* %a0.coerce1) +// CHECK: define void @_Z2f05f0_s1(i32 %a0.coerce0, i8* %a0.coerce1) void f0(f0_s1 a0) { } // Check with two eight-bytes in base class. struct f1_s0 { unsigned a; unsigned b; float c; }; struct f1_s1 : public f1_s0 { float d;}; -// CHECK: define void @_Z2f15f1_s1(i64 %a0.coerce0, double %a0.coerce1) +// CHECK: define void @_Z2f15f1_s1(i64 %a0.coerce0, <2 x float> %a0.coerce1) void f1(f1_s1 a0) { } // Check with two eight-bytes in base class and merge. @@ -54,7 +54,7 @@ namespace PR7742 { // Also rdar://8250764 struct c2 : public s2 {}; - // CHECK: define double @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P) + // CHECK: define <2 x float> @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P) c2 foo(c2 *P) { } |