diff options
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r-- | test/CodeGenCXX/2010-03-09-AnonAggregate.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/PR6474.cpp | 31 | ||||
-rw-r--r-- | test/CodeGenCXX/default-destructor-nested.cpp | 13 | ||||
-rw-r--r-- | test/CodeGenCXX/internal-linkage.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-system-header.cpp | 4 | ||||
-rw-r--r-- | test/CodeGenCXX/nullptr.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/virtual-base-destructor-call.cpp | 10 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-layout-abi-examples.cpp | 123 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-layout.cpp | 55 |
9 files changed, 257 insertions, 9 deletions
diff --git a/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp new file mode 100644 index 0000000..99883d8 --- /dev/null +++ b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -g -S -o %t %s +// PR: 6554 +// More then one anonymous aggregates on one line creates chaos when MDNode uniquness is +// combined with RAUW operation. +// This test case causes crashes if malloc is configured to trip buffer overruns. +class MO { + + union { struct { union { int BA; } Val; int Offset; } OffsetedInfo; } Contents; + +}; + +class MO m; diff --git a/test/CodeGenCXX/PR6474.cpp b/test/CodeGenCXX/PR6474.cpp new file mode 100644 index 0000000..68c09c9 --- /dev/null +++ b/test/CodeGenCXX/PR6474.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -emit-llvm + +namespace test0 { +template <typename T> struct X { + virtual void foo(); + virtual void bar(); + virtual void baz(); +}; + +template <typename T> void X<T>::foo() {} +template <typename T> void X<T>::bar() {} +template <typename T> void X<T>::baz() {} + +template <> void X<char>::foo() {} +template <> void X<char>::bar() {} +} + +namespace test1 { +template <typename T> struct X { + virtual void foo(); + virtual void bar(); + virtual void baz(); +}; + +template <typename T> void X<T>::foo() {} +template <typename T> void X<T>::bar() {} +template <typename T> void X<T>::baz() {} + +template <> void X<char>::bar() {} +template <> void X<char>::foo() {} +} diff --git a/test/CodeGenCXX/default-destructor-nested.cpp b/test/CodeGenCXX/default-destructor-nested.cpp new file mode 100644 index 0000000..8694274 --- /dev/null +++ b/test/CodeGenCXX/default-destructor-nested.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -emit-llvm-only +// PR6294 + +class A { + virtual ~A(); +}; +class B { + class C; +}; +class B::C : public A { + C(); +}; +B::C::C() {} diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp index 1ae0f08..4263891 100644 --- a/test/CodeGenCXX/internal-linkage.cpp +++ b/test/CodeGenCXX/internal-linkage.cpp @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -struct Global { }; -template<typename T> struct X { }; +struct Global { Global(); }; +template<typename T> struct X { X(); }; namespace { - struct Anon { }; + struct Anon { Anon(); }; // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global Global anon0; diff --git a/test/CodeGenCXX/mangle-system-header.cpp b/test/CodeGenCXX/mangle-system-header.cpp index cb68bc1..6716b58 100644 --- a/test/CodeGenCXX/mangle-system-header.cpp +++ b/test/CodeGenCXX/mangle-system-header.cpp @@ -5,3 +5,7 @@ # 1 "fake_system_header.h" 1 3 4 // CHECK: define void @_ZdlPvS_( void operator delete (void*, void*) {} + +// PR6217 +// CHECK: define void @_Z3barv() +void bar() { } diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp index 31bd475..ab63b43 100644 --- a/test/CodeGenCXX/nullptr.cpp +++ b/test/CodeGenCXX/nullptr.cpp @@ -1,7 +1,17 @@ -// RUN: %clang_cc1 -std=c++0x %s -emit-llvm -o %t +// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s int* a = nullptr; void f() { int* a = nullptr; } + +typedef decltype(nullptr) nullptr_t; + +nullptr_t get_nullptr(); + +struct X { }; +void g() { + // CHECK: call i8* @_Z11get_nullptrv() + int (X::*pmf)(int) = get_nullptr(); +} diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp index b6e85e2..7de9dd2 100644 --- a/test/CodeGenCXX/virtual-base-destructor-call.cpp +++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp @@ -22,6 +22,11 @@ int main() { // CHECK: call void @_ZN14basic_iostreamIcED2Ev // CHECK: call void @_ZN9basic_iosD2Ev +// basic_iostream's base dtor calls its non-virtual base dtor. +// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev +// CHECK: call void @_ZN13basic_istreamIcED2Ev +// CHECK: } + // basic_iostream's deleting dtor calls its complete dtor, then // operator delete(). // CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev @@ -40,11 +45,6 @@ int main() { // CHECK: call void @_ZN13basic_istreamIcED1Ev // CHECK: call void @_ZdlPv -// basic_iostream's base dtor calls its non-virtual base dtor. -// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev -// CHECK: call void @_ZN13basic_istreamIcED2Ev -// CHECK: } - // basic_istream's base dtor is a no-op. // CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev // CHECK-NOT: call diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp index 2c6b7a4..a82fca7 100644 --- a/test/CodeGenCXX/vtable-layout-abi-examples.cpp +++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp @@ -187,3 +187,126 @@ struct D : public B, public C { void D::d() { } } + +namespace Test3 { + +// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor + +struct V1 { + int v1; + virtual void f(); +}; + +struct V2 : virtual V1 { + int v2; + virtual void f(); +}; + +// CHECK: Vtable for 'Test3::C' (14 entries). +// CHECK-NEXT: 0 | vbase_offset (32) +// CHECK-NEXT: 1 | vbase_offset (16) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-NEXT: 4 | void Test3::C::f() +// CHECK-NEXT: 5 | vcall_offset (-16) +// CHECK-NEXT: 6 | offset_to_top (-16) +// CHECK-NEXT: 7 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- +// CHECK-NEXT: 8 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-NEXT: 9 | vcall_offset (-32) +// CHECK-NEXT: 10 | vbase_offset (-16) +// CHECK-NEXT: 11 | offset_to_top (-32) +// CHECK-NEXT: 12 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- +// CHECK-NEXT: 13 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] + +// CHECK: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries). +// CHECK-NEXT: 0 | vcall_offset (0) +// CHECK-NEXT: 1 | vbase_offset (-16) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test3::V2 RTTI +// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- +// CHECK-NEXT: 4 | void Test3::V2::f() +// CHECK-NEXT: 5 | vcall_offset (16) +// CHECK-NEXT: 6 | offset_to_top (16) +// CHECK-NEXT: 7 | Test3::V2 RTTI +// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- +// CHECK-NEXT: 8 | void Test3::V2::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +struct C : virtual V1, virtual V2 { + int c; + virtual void f(); +}; +void C::f() { } + +struct B { + int b; +}; + +// CHECK: Vtable for 'Test3::D' (15 entries). +// CHECK-NEXT: 0 | vbase_offset (40) +// CHECK-NEXT: 1 | vbase_offset (24) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test3::D RTTI +// CHECK-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-NEXT: -- (Test3::D, 0) vtable address -- +// CHECK-NEXT: 4 | void Test3::C::f() +// CHECK-NEXT: 5 | void Test3::D::g() +// CHECK-NEXT: 6 | vcall_offset (-24) +// CHECK-NEXT: 7 | offset_to_top (-24) +// CHECK-NEXT: 8 | Test3::D RTTI +// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-NEXT: 9 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-NEXT: 10 | vcall_offset (-40) +// CHECK-NEXT: 11 | vbase_offset (-16) +// CHECK-NEXT: 12 | offset_to_top (-40) +// CHECK-NEXT: 13 | Test3::D RTTI +// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-NEXT: 14 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] + +// CHECK: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries). +// CHECK-NEXT: 0 | vbase_offset (40) +// CHECK-NEXT: 1 | vbase_offset (24) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-NEXT: 4 | void Test3::C::f() +// CHECK-NEXT: 5 | vcall_offset (-24) +// CHECK-NEXT: 6 | offset_to_top (-24) +// CHECK-NEXT: 7 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-NEXT: 8 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-NEXT: 9 | vcall_offset (-40) +// CHECK-NEXT: 10 | vbase_offset (-16) +// CHECK-NEXT: 11 | offset_to_top (-40) +// CHECK-NEXT: 12 | Test3::C RTTI +// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-NEXT: 13 | void Test3::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] + +// CHECK: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries). +// CHECK-NEXT: 0 | vcall_offset (0) +// CHECK-NEXT: 1 | vbase_offset (-16) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test3::V2 RTTI +// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-NEXT: 4 | void Test3::V2::f() +// CHECK-NEXT: 5 | vcall_offset (16) +// CHECK-NEXT: 6 | offset_to_top (16) +// CHECK-NEXT: 7 | Test3::V2 RTTI +// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-NEXT: 8 | void Test3::V2::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +struct D : B, C { + int d; + virtual void g(); +}; +void D::g() { } + +} diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index a65af6e..5c783f1 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -1036,3 +1036,58 @@ struct C : A, virtual V, B { void C::g() { } } + +namespace Test26 { + +// Test that we generate the right number of entries in the C-in-D construction vtable, and that +// we don't mark A::a as unused. + +struct A { + virtual void a(); +}; + +struct B { + virtual void c(); +}; + +struct C : virtual A { + virtual void b(); +}; + +// CHECK: Vtable for 'Test26::D' (15 entries). +// CHECK-NEXT: 0 | vbase_offset (8) +// CHECK-NEXT: 1 | vbase_offset (8) +// CHECK-NEXT: 2 | vbase_offset (0) +// CHECK-NEXT: 3 | vcall_offset (0) +// CHECK-NEXT: 4 | offset_to_top (0) +// CHECK-NEXT: 5 | Test26::D RTTI +// CHECK-NEXT: -- (Test26::B, 0) vtable address -- +// CHECK-NEXT: -- (Test26::D, 0) vtable address -- +// CHECK-NEXT: 6 | void Test26::B::c() +// CHECK-NEXT: 7 | void Test26::D::d() +// CHECK-NEXT: 8 | vcall_offset (0) +// CHECK-NEXT: 9 | vbase_offset (0) +// CHECK-NEXT: 10 | vcall_offset (0) +// CHECK-NEXT: 11 | offset_to_top (-8) +// CHECK-NEXT: 12 | Test26::D RTTI +// CHECK-NEXT: -- (Test26::A, 8) vtable address -- +// CHECK-NEXT: -- (Test26::C, 8) vtable address -- +// CHECK-NEXT: 13 | void Test26::A::a() +// CHECK-NEXT: 14 | void Test26::C::b() + +// CHECK: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries). +// CHECK-NEXT: 0 | vcall_offset (0) +// CHECK-NEXT: 1 | vbase_offset (0) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test26::C RTTI +// CHECK-NEXT: -- (Test26::A, 8) vtable address -- +// CHECK-NEXT: -- (Test26::C, 8) vtable address -- +// CHECK-NEXT: 5 | void Test26::A::a() +// CHECK-NEXT: 6 | void Test26::C::b() +class D : virtual B, virtual C { + virtual void d(); +}; +void D::d() { } + +} |