diff options
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r-- | test/CodeGenCXX/2012-03-16-StoreAlign.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/cfi-ms-rtti.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/cfi-vcall.cpp | 23 | ||||
-rw-r--r-- | test/CodeGenCXX/debug-info-namespace.cpp | 3 | ||||
-rw-r--r-- | test/CodeGenCXX/eh-aggregate-copy-destroy.cpp | 37 | ||||
-rw-r--r-- | test/CodeGenCXX/eh-aggregated-inits-unwind.cpp | 47 | ||||
-rw-r--r-- | test/CodeGenCXX/eh-aggregated-inits.cpp | 46 | ||||
-rw-r--r-- | test/CodeGenCXX/exceptions-seh-filter-captures.cpp | 14 | ||||
-rw-r--r-- | test/CodeGenCXX/exceptions-seh.cpp | 4 | ||||
-rw-r--r-- | test/CodeGenCXX/pr24097.cpp | 20 | ||||
-rw-r--r-- | test/CodeGenCXX/sanitize-dtor-callback.cpp | 17 | ||||
-rw-r--r-- | test/CodeGenCXX/varargs.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/x86_64-arguments-avx.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/x86_64-arguments.cpp | 16 |
14 files changed, 239 insertions, 13 deletions
diff --git a/test/CodeGenCXX/2012-03-16-StoreAlign.cpp b/test/CodeGenCXX/2012-03-16-StoreAlign.cpp index 7e82ca544dc0..5f6189e2451b 100644 --- a/test/CodeGenCXX/2012-03-16-StoreAlign.cpp +++ b/test/CodeGenCXX/2012-03-16-StoreAlign.cpp @@ -28,7 +28,7 @@ struct Foo { }; // CHECK: @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth = linkonce_odr global %struct.Length zeroinitializer, align 4 -// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length, %struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 1 +// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length, %struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 4 bool bar(Length &b) { Foo f; diff --git a/test/CodeGenCXX/cfi-ms-rtti.cpp b/test/CodeGenCXX/cfi-ms-rtti.cpp new file mode 100644 index 000000000000..5203a6bb0c8b --- /dev/null +++ b/test/CodeGenCXX/cfi-ms-rtti.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s +// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s + +struct A { + A(); + virtual void f() {} +}; + +A::A() {} + +// RTTI: !{!"A@@", [2 x i8*]* {{.*}}, i64 8} +// NO-RTTI: !{!"A@@", [1 x i8*]* {{.*}}, i64 0} diff --git a/test/CodeGenCXX/cfi-vcall.cpp b/test/CodeGenCXX/cfi-vcall.cpp index 333c7bd1f160..5cb5e02cf585 100644 --- a/test/CodeGenCXX/cfi-vcall.cpp +++ b/test/CodeGenCXX/cfi-vcall.cpp @@ -134,6 +134,29 @@ void foo() { af(&fa); } +namespace test2 { + +struct A { + virtual void m_fn1(); +}; +struct B { + virtual void m_fn2(); +}; +struct C : B, A {}; +struct D : C { + void m_fn1(); +}; + +// ITANIUM: define void @_ZN5test21fEPNS_1DE +// MS: define void @"\01?f@test2@@YAXPEAUD@1@@Z" +void f(D *d) { + // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"N5test21DE") + // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"A@test2@@") + d->m_fn1(); +} + +} + // Check for the expected number of elements (9 or 15 respectively). // MS: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){8}]]} // ITANIUM: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){14}]]} diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 35b371ec9c9d..8a00d9b4a5eb 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -104,8 +104,7 @@ void B::func_fwd() {} // CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit( // CHECK-GMLT-SAME: emissionKind: 2, -// CHECK-GMLT-SAME: imports: [[MODULES:![0-9]+]] -// CHECK-GMLT: [[MODULES]] = !{} +// CHECK-GMLT-NOT: imports: // CHECK-NOLIMIT: !DICompositeType(tag: DW_TAG_structure_type, name: "bar",{{.*}} line: 6, // CHECK-NOLIMIT-NOT: DIFlagFwdDecl diff --git a/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp b/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp new file mode 100644 index 000000000000..29fb5567fb1d --- /dev/null +++ b/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp @@ -0,0 +1,37 @@ +// Check that in case of copying an array of memcpy-able objects, their +// destructors will be called if an exception is thrown. +// +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s + +struct ImplicitCopy { + int x; + ImplicitCopy() { x = 10; } + ~ImplicitCopy() { x = 20; } +}; + +struct ThrowCopy { + ThrowCopy() {} + ThrowCopy(const ThrowCopy &) { throw 1; } +}; + +struct Container { + ImplicitCopy b[2]; + ThrowCopy c; +}; + +int main () { + try { + Container c1; + // CHECK_LABEL: main + // CHECK-NOT: call void @_ZN9ThrowCopyC1ERKS_ + // CHECK: invoke void @_ZN9ThrowCopyC1ERKS_ + // CHECK: invoke void @_ZN12ImplicitCopyD1Ev + Container c2(c1); + } + catch (...) { + return 1; + } + + return 0; +} + diff --git a/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp b/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp new file mode 100644 index 000000000000..9772564b051c --- /dev/null +++ b/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp @@ -0,0 +1,47 @@ +// Check that destructors of memcpy-able struct members are called properly +// during stack unwinding after an exception. +// +// Check that destructor's argument (address of member to be destroyed) is +// obtained by taking offset from struct, not by bitcasting pointers. +// +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s + +struct ImplicitCopy { + int id; + ImplicitCopy() { id = 10; } + ~ImplicitCopy() { id = 20; } +}; + +struct ThrowCopy { + int id; + ThrowCopy() { id = 15; } + ThrowCopy(const ThrowCopy &x) { + id = 25; + throw 1; + } + ~ThrowCopy() { id = 35; } +}; + +struct Container { + int id; + ImplicitCopy o1; + ThrowCopy o2; + + Container() { id = 1000; } + ~Container() { id = 2000; } +}; + +int main() { + try { + Container c1; + // CHECK-LABEL: main + // CHECK: %{{.+}} = getelementptr inbounds %struct.Container, %struct.Container* %{{.+}}, i32 0, i32 1 + // CHECK-NOT: %{{.+}} = bitcast %struct.Container* %{{.+}} to %struct.ImplicitCopy* + Container c2(c1); + + return 2; + } catch (...) { + return 1; + } + return 0; +} diff --git a/test/CodeGenCXX/eh-aggregated-inits.cpp b/test/CodeGenCXX/eh-aggregated-inits.cpp new file mode 100644 index 000000000000..cb34b65dfe8e --- /dev/null +++ b/test/CodeGenCXX/eh-aggregated-inits.cpp @@ -0,0 +1,46 @@ +// Check that initialization of the only one memcpy-able struct member will not +// be performed twice after successful non-trivial initializtion of the second +// member. +// +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s + +int globId = 0; + +struct ImplicitCopy { + int id; + + ImplicitCopy() { id = 10; } + ~ImplicitCopy() { id = 20; } +}; + +struct ExplicitCopy { + int id; + + ExplicitCopy() { id = 15; } + ExplicitCopy(const ExplicitCopy &x) { id = 25; } + ~ExplicitCopy() { id = 35; } +}; + +struct Container { + ImplicitCopy o1; // memcpy-able member. + ExplicitCopy o2; // non-trivial initialization. + + Container() { globId = 1000; } + ~Container() { globId = 2000; } +}; + +int main() { + try { + Container c1; + // CHECK-DAG: call void @llvm.memcpy + // CHECK-DAG: declare void @llvm.memcpy + // CHECK-NOT: @llvm.memcpy + Container c2(c1); + + return 2; + } + catch (...) { + return 1; + } + return 0; +} diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp index 5df418a13ad8..26ef90f5a6f3 100644 --- a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp +++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -15,15 +15,15 @@ extern "C" void test_freefunc(int p1) { } // CHECK-LABEL: define void @test_freefunc(i32 %p1) -// CHECK: @llvm.frameescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]]) +// CHECK: @llvm.localescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]]) // CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4 // CHECK: store i32 13, i32* %[[l1_ptr]], align 4 // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32* -// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1) // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* // CHECK: %[[s1:[^ ]*]] = load i32, i32* @"\01?s1@?1??test_freefunc@@9@4HA", align 4 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] @@ -45,12 +45,12 @@ void S::test_method() { } // CHECK-LABEL: define void @"\01?test_method@S@@QEAAXXZ"(%struct.S* %this) -// CHECK: @llvm.frameescape(i32* %[[l1_addr:[^, ]*]]) +// CHECK: @llvm.localescape(i32* %[[l1_addr:[^, ]*]]) // CHECK: store i32 13, i32* %[[l1_addr]], align 4 // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]]) @@ -69,12 +69,12 @@ void test_lambda() { } // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) -// CHECK: @llvm.frameescape(i32* %[[l2_addr:[^, ]*]]) +// CHECK: @llvm.localescape(i32* %[[l2_addr:[^, ]*]]) // CHECK: store i32 42, i32* %[[l2_addr]], align 4 // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@?R<lambda_0>@?test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32* // CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]] // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]]) diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp index 2cee4f77e5d4..187ad4bc710e 100644 --- a/test/CodeGenCXX/exceptions-seh.cpp +++ b/test/CodeGenCXX/exceptions-seh.cpp @@ -127,13 +127,13 @@ void use_inline() { // // CHECK: invoke void @might_throw() // -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]]) // CHECK: ret void // // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]]) // CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) diff --git a/test/CodeGenCXX/pr24097.cpp b/test/CodeGenCXX/pr24097.cpp new file mode 100644 index 000000000000..122bf88506d3 --- /dev/null +++ b/test/CodeGenCXX/pr24097.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-optzns -o - | FileCheck %s + +struct Filter { + virtual void Foo(); +}; +struct Sender { + virtual bool Send(); +}; +struct SyncMessageFilter : public Filter, public Sender { + bool Send(); +}; +struct TestSyncMessageFilter : public SyncMessageFilter { +}; +void bar() { + TestSyncMessageFilter f; + f.Send(); +} + +// Test that it is not hidden +// CHECK: define available_externally zeroext i1 @_ZThn8_N17SyncMessageFilter4SendEv diff --git a/test/CodeGenCXX/sanitize-dtor-callback.cpp b/test/CodeGenCXX/sanitize-dtor-callback.cpp new file mode 100644 index 000000000000..4912a27229f9 --- /dev/null +++ b/test/CodeGenCXX/sanitize-dtor-callback.cpp @@ -0,0 +1,17 @@ +// Test -fsanitize-memory-use-after-dtor +// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fsanitize=memory -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s -check-prefix=NO_DTOR_CHECK + +struct Simple { + ~Simple() {} +}; +Simple s; +// Simple internal member is poisoned by compiler-generated dtor +// CHECK-LABEL: @_ZN6SimpleD2Ev +// CHECK: call void @__sanitizer_dtor_callback +// CHECK: ret void + +// Compiling without the flag does not generate member-poisoning dtor +// NO_DTOR_CHECK-LABEL: @_ZN6SimpleD2Ev +// NO_DTOR_CHECK-NOT: call void @sanitizer_dtor_callback +// NO_DTOR_CHECK: ret void diff --git a/test/CodeGenCXX/varargs.cpp b/test/CodeGenCXX/varargs.cpp index 1ea072e2eb5a..e0165994d013 100644 --- a/test/CodeGenCXX/varargs.cpp +++ b/test/CodeGenCXX/varargs.cpp @@ -37,7 +37,7 @@ namespace test1 { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[X]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 8, i32 4, i1 false) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i64* - // CHECK-NEXT: [[T1:%.*]] = load i64, i64* [[T0]], align 1 + // CHECK-NEXT: [[T1:%.*]] = load i64, i64* [[T0]], align 4 // CHECK-NEXT: call void (...) @_ZN5test13fooEz(i64 [[T1]]) // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/x86_64-arguments-avx.cpp b/test/CodeGenCXX/x86_64-arguments-avx.cpp index 29e693451d12..2933d9445b76 100644 --- a/test/CodeGenCXX/x86_64-arguments-avx.cpp +++ b/test/CodeGenCXX/x86_64-arguments-avx.cpp @@ -50,3 +50,12 @@ UU2 PR23082(UU2 x) { return x; } } + +namespace test3 { +union U { + __attribute__((__vector_size__(32))) float f1; + int f2; +}; +// CHECK: define i32 @_ZN5test31fENS_1UE({{.*}}* byval align 32 +int f(U u) { return u.f2; } +} diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp index 815ef6111a9a..64202b4d02c6 100644 --- a/test/CodeGenCXX/x86_64-arguments.cpp +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -196,3 +196,19 @@ namespace test9 { return sret; } } + +namespace test10 { +#pragma pack(1) +struct BasePacked { + char one; + short two; +}; +#pragma pack() +struct DerivedPacked : public BasePacked { + int three; +}; +// CHECK-LABEL: define i32 @_ZN6test1020FuncForDerivedPackedENS_13DerivedPackedE({{.*}}* byval align 8 +int FuncForDerivedPacked(DerivedPacked d) { + return d.three; +} +} |