aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/2012-03-16-StoreAlign.cpp2
-rw-r--r--test/CodeGenCXX/cfi-ms-rtti.cpp12
-rw-r--r--test/CodeGenCXX/cfi-vcall.cpp23
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp3
-rw-r--r--test/CodeGenCXX/eh-aggregate-copy-destroy.cpp37
-rw-r--r--test/CodeGenCXX/eh-aggregated-inits-unwind.cpp47
-rw-r--r--test/CodeGenCXX/eh-aggregated-inits.cpp46
-rw-r--r--test/CodeGenCXX/exceptions-seh-filter-captures.cpp14
-rw-r--r--test/CodeGenCXX/exceptions-seh.cpp4
-rw-r--r--test/CodeGenCXX/pr24097.cpp20
-rw-r--r--test/CodeGenCXX/sanitize-dtor-callback.cpp17
-rw-r--r--test/CodeGenCXX/varargs.cpp2
-rw-r--r--test/CodeGenCXX/x86_64-arguments-avx.cpp9
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp16
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;
+}
+}