diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
commit | 2e645aa5697838f16ec570eb07c2bee7e13d0e0b (patch) | |
tree | a764184c2fc9486979b074250b013a0937ee64e5 /test/CodeGenCXX | |
parent | 798321d8eb5630cd4a8f490a4f25e32ef195fb07 (diff) |
Notes
Diffstat (limited to 'test/CodeGenCXX')
26 files changed, 316 insertions, 92 deletions
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index 7d94cba7ff11..0fadfe97b49a 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -291,7 +291,7 @@ namespace test7 { // Static and guard tested at top of file - // CHECK-LABEL: define void @_ZN5test74testEv() + // CHECK-LABEL: define void @_ZN5test74testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) void test() { // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 1 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 @@ -311,7 +311,7 @@ namespace test7 { // CHECK: ret void static int x = foo(); - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) // CHECK: resume { i8*, i32 } @@ -326,7 +326,7 @@ namespace test8 { // Static and guard tested at top of file - // CHECK-LABEL: define void @_ZN5test84testEv() + // CHECK-LABEL: define void @_ZN5test84testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) void test() { // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 1 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 @@ -351,7 +351,7 @@ namespace test8 { // CHECK: ret void static A x; - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) // CHECK: resume { i8*, i32 } diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp index a47099c11b44..5e5174bd06e4 100644 --- a/test/CodeGenCXX/atomicinit.cpp +++ b/test/CodeGenCXX/atomicinit.cpp @@ -65,15 +65,15 @@ namespace PR18097 { }; // CHECK-LABEL: define {{.*}} @__cxx_global_var_init - // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1aE, i32 1) + // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1aE, i32 1) _Atomic(X) a = X(1); // CHECK-LABEL: define {{.*}} @__cxx_global_var_init - // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1bE, i32 2) + // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1bE, i32 2) _Atomic(X) b(X(2)); // CHECK-LABEL: define {{.*}} @__cxx_global_var_init - // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1cE, i32 3) + // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1cE, i32 3) _Atomic(X) c{X(3)}; struct Y { diff --git a/test/CodeGenCXX/cfi-cast.cpp b/test/CodeGenCXX/cfi-cast.cpp index c671bad7efa2..09089634442c 100644 --- a/test/CodeGenCXX/cfi-cast.cpp +++ b/test/CodeGenCXX/cfi-cast.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s // In this test the main thing we are searching for is something like // 'metadata !"1B"' where "1B" is the mangled name of the class we are @@ -19,7 +19,7 @@ struct C : A {}; // CHECK-DCAST-LABEL: define void @_Z3abpP1A void abp(A *a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -33,7 +33,7 @@ void abp(A *a) { // CHECK-DCAST-LABEL: define void @_Z3abrR1A void abr(A &a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -47,7 +47,7 @@ void abr(A &a) { // CHECK-DCAST-LABEL: define void @_Z4abrrO1A void abrr(A &&a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -61,7 +61,7 @@ void abrr(A &&a) { // CHECK-UCAST-LABEL: define void @_Z3vbpPv void vbp(void *p) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() @@ -75,7 +75,7 @@ void vbp(void *p) { // CHECK-UCAST-LABEL: define void @_Z3vbrRc void vbr(char &r) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() @@ -89,7 +89,7 @@ void vbr(char &r) { // CHECK-UCAST-LABEL: define void @_Z4vbrrOc void vbrr(char &&r) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() diff --git a/test/CodeGenCXX/cfi-vcall.cpp b/test/CodeGenCXX/cfi-vcall.cpp index b0f79d9ec0ea..333c7bd1f160 100644 --- a/test/CodeGenCXX/cfi-vcall.cpp +++ b/test/CodeGenCXX/cfi-vcall.cpp @@ -1,4 +1,15 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=NDIAG %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-ABORT %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS --check-prefix=NDIAG %s + +// MS: @[[VTA:[0-9]*]] {{.*}} comdat($"\01??_7A@@6B@") +// MS: @[[VTB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6B0@@") +// MS: @[[VTAinB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6BA@@@") +// MS: @[[VTAinC:[0-9]*]] {{.*}} comdat($"\01??_7C@@6B@") +// MS: @[[VTBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BB@@@") +// MS: @[[VTAinBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BA@@@") +// MS: @[[VTFA:[0-9]*]] {{.*}} comdat($"\01??_7FA@?1??foo@@YAXXZ@6B@") struct A { A(); @@ -7,6 +18,8 @@ struct A { struct B : virtual A { B(); + virtual void g(); + virtual void h(); }; struct C : virtual A { @@ -18,6 +31,7 @@ namespace { struct D : B, C { D(); virtual void f(); + virtual void h(); }; } @@ -30,37 +44,75 @@ D::D() {} void A::f() { } +void B::g() { +} + void D::f() { } -// CHECK: define void @_Z2afP1A +void D::h() { +} + +// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}cfi-vcall.cpp\00", align 1 +// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" } +// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8 } { { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+21]], i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]], i8 0 } + +// ITANIUM: define void @_Z2afP1A +// MS: define void @"\01?af@@YAXPEAUA@@@Z" void af(A *a) { - // CHECK: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") - // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"1A") + // MS: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"A@@") + // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]] + // CHECK-NEXT: {{^$}} // CHECK: [[TRAPBB]] - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: unreachable + // NDIAG-NEXT: call void @llvm.trap() + // NDIAG-NEXT: unreachable + // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64 + // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_bad_type_abort(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]]) + // DIAG-ABORT-NEXT: unreachable + // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_bad_type(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]]) + // DIAG-RECOVER-NEXT: br label %[[CONTBB]] // CHECK: [[CONTBB]] // CHECK: call void % a->f(); } -// CHECK: define internal void @_Z3df1PN12_GLOBAL__N_11DE +// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE +// MS: define internal void @"\01?df1@@YAXPEAUD@?A@@@Z" void df1(D *d) { - // CHECK: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE") + // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE") + // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"A@@") d->f(); } -// CHECK: define internal void @_Z3df2PN12_GLOBAL__N_11DE +// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE +// MS: define internal void @"\01?dg1@@YAXPEAUD@?A@@@Z" +void dg1(D *d) { + // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"B@@") + d->g(); +} + +// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE +// MS: define internal void @"\01?dh1@@YAXPEAUD@?A@@@Z" +void dh1(D *d) { + // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE") + // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]D@?A@@") + d->h(); +} + +// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE +// MS: define internal void @"\01?df2@@YAXPEAUD@?A@@@Z" __attribute__((no_sanitize("cfi"))) void df2(D *d) { // CHECK-NOT: call i1 @llvm.bitset.test d->f(); } -// CHECK: define internal void @_Z3df3PN12_GLOBAL__N_11DE +// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE +// MS: define internal void @"\01?df3@@YAXPEAUD@?A@@@Z" __attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall"))) void df3(D *d) { // CHECK-NOT: call i1 @llvm.bitset.test @@ -71,20 +123,43 @@ D d; void foo() { df1(&d); + dg1(&d); + dh1(&d); df2(&d); df3(&d); + + struct FA : A { + void f() {} + } fa; + af(&fa); } -// CHECK-DAG: !{!"1A", [3 x i8*]* @_ZTV1A, i64 16} -// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} -// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} -// CHECK-DAG: !{!"1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64} -// CHECK-DAG: !{!"1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32} -// CHECK-DAG: !{!"1A", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} -// CHECK-DAG: !{!"1B", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} -// CHECK-DAG: !{!"1C", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 72} -// CHECK-DAG: !{!"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} -// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1B, i64 32} -// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTV1B, i64 32} -// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1C, i64 32} -// CHECK-DAG: !{!"1C", [5 x i8*]* @_ZTV1C, i64 32} +// Check for the expected number of elements (9 or 15 respectively). +// MS: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){8}]]} +// ITANIUM: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){14}]]} + +// ITANIUM-DAG: !{!"1A", [3 x i8*]* @_ZTV1A, i64 16} +// ITANIUM-DAG: !{!"1A", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} +// ITANIUM-DAG: !{!"1B", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} +// ITANIUM-DAG: !{!"1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64} +// ITANIUM-DAG: !{!"1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32} +// ITANIUM-DAG: !{!"1A", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// ITANIUM-DAG: !{!"1B", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// ITANIUM-DAG: !{!"1C", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 88} +// ITANIUM-DAG: !{!"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// ITANIUM-DAG: !{!"1A", [7 x i8*]* @_ZTV1B, i64 32} +// ITANIUM-DAG: !{!"1B", [7 x i8*]* @_ZTV1B, i64 32} +// ITANIUM-DAG: !{!"1A", [5 x i8*]* @_ZTV1C, i64 32} +// ITANIUM-DAG: !{!"1C", [5 x i8*]* @_ZTV1C, i64 32} +// ITANIUM-DAG: !{!"1A", [3 x i8*]* @_ZTVZ3foovE2FA, i64 16} +// ITANIUM-DAG: !{!"[{{.*}}cfi-vcall.cpp]Z3foovE2FA", [3 x i8*]* @_ZTVZ3foovE2FA, i64 16} + +// MS-DAG: !{!"A@@", [2 x i8*]* @[[VTA]], i64 8} +// MS-DAG: !{!"B@@", [3 x i8*]* @[[VTB]], i64 8} +// MS-DAG: !{!"A@@", [2 x i8*]* @[[VTAinB]], i64 8} +// MS-DAG: !{!"A@@", [2 x i8*]* @[[VTAinC]], i64 8} +// MS-DAG: !{!"B@@", [3 x i8*]* @[[VTBinD]], i64 8} +// MS-DAG: !{!"[{{.*}}cfi-vcall.cpp]D@?A@@", [3 x i8*]* @[[VTBinD]], i64 8} +// MS-DAG: !{!"A@@", [2 x i8*]* @[[VTAinBinD]], i64 8} +// MS-DAG: !{!"A@@", [2 x i8*]* @[[VTFA]], i64 8} +// MS-DAG: !{!"[{{.*}}cfi-vcall.cpp]FA@?1??foo@@YAXXZ@", [2 x i8*]* @[[VTFA]], i64 8} diff --git a/test/CodeGenCXX/ctor-globalopt.cpp b/test/CodeGenCXX/ctor-globalopt.cpp index 672fc9067527..26ec523c553b 100644 --- a/test/CodeGenCXX/ctor-globalopt.cpp +++ b/test/CodeGenCXX/ctor-globalopt.cpp @@ -13,7 +13,7 @@ // CHECK-LABEL: define internal void @_GLOBAL__sub_I_ctor_globalopt.cpp() // CHECK: call void @ -// CHECK-NOT: call +// CHECK-NOT: call{{ }} // O1: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp index 3fb5c15c2ab5..a3dff79fc494 100644 --- a/test/CodeGenCXX/cxx11-exception-spec.cpp +++ b/test/CodeGenCXX/cxx11-exception-spec.cpp @@ -13,7 +13,7 @@ template<typename T> struct S { // CHECK: define {{.*}} @_Z1fIsEvv() [[NONE:#[0-9]+]] { template<> void f<short>() { h(); } -// CHECK: define {{.*}} @_Z1fIA2_sEvv() [[NUW:#[0-9]+]] { +// CHECK: define {{.*}} @_Z1fIA2_sEvv() [[NUW:#[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { template<> void f<short[2]>() noexcept { h(); } // CHECK: define {{.*}} @_ZN1SIsE1fEv() @@ -24,7 +24,7 @@ template<> void S<short[2]>::f() noexcept { h(); } // CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] comdat { template void f<char16_t>(); -// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] comdat { +// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { template void f<char16_t[2]>(); // CHECK: define {{.*}} @_ZN1SIDsE1fEv() @@ -34,7 +34,7 @@ template void S<char16_t>::f(); template void S<char16_t[2]>::f(); void h() { - // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] comdat { + // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { f<int>(); // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] comdat { f<int[2]>(); @@ -45,7 +45,7 @@ void h() { // CHECK-NOT: [[NUW]] S<int[2]>::f(); - // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] comdat { + // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { void (*f1)() = &f<float>; // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] comdat { void (*f2)() = &f<double>; @@ -56,7 +56,7 @@ void h() { // CHECK-NOT: [[NUW]] void (*f4)() = &S<double>::f; - // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] comdat { + // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { (void)&f<char[4]>; // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] comdat { (void)&f<char>; diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index 2918cf39775b..b47c6c6b1d43 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -191,10 +191,11 @@ namespace test3 { // CHECK4: ret void // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr + // CHECK4-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK4: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev // CHECK4: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]] // CHECK4: ret void - // CHECK4: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK4: landingpad { i8*, i32 } // CHECK4-NEXT: cleanup // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]] // CHECK4: resume { i8*, i32 } @@ -210,10 +211,11 @@ namespace test3 { // CHECK4: ret void // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr + // CHECK4-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK4: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev( // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]] // CHECK4: ret void - // CHECK4: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK4: landingpad { i8*, i32 } // CHECK4-NEXT: cleanup // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]] // CHECK4: resume { i8*, i32 } diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 477e7dcf0b53..0eb6476bd0ec 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -532,6 +532,22 @@ struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {}; // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ" +namespace PR23801 { +template <typename> +struct S { + ~S() {} +}; +struct A { + A(int); + S<int> s; +}; +struct __declspec(dllexport) B { + B(A = 0) {} +}; +} +// +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ" + struct __declspec(dllexport) T { // Copy assignment operator: // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z" diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp index fe85e212b669..9467f3e80d8c 100644 --- a/test/CodeGenCXX/dynamic-cast.cpp +++ b/test/CodeGenCXX/dynamic-cast.cpp @@ -3,6 +3,7 @@ struct A { virtual void f(); }; struct B : A { }; // CHECK: {{define.*@_Z1fP1A}} +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) B fail; const B& f(A *a) { try { @@ -11,7 +12,7 @@ const B& f(A *a) { // CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]] dynamic_cast<const B&>(*a); } catch (...) { - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: catch i8* null } return fail; diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 77655f0b9f0f..b44e8144bb27 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -102,6 +102,7 @@ namespace test6 { // PR7127 namespace test7 { // CHECK-LABEL: define i32 @_ZN5test73fooEv() +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) int foo() { // CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8* // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 @@ -115,7 +116,7 @@ namespace test7 { throw 1; } -// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) // CHECK-NEXT: catch i8* null // CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 @@ -137,7 +138,7 @@ namespace test7 { throw; } } -// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } // CHECK-NEXT: catch i8* null // CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] @@ -186,11 +187,12 @@ namespace test9 { // CHECK-LABEL: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr + // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) A::A() try { // CHECK: invoke void @_ZN5test96opaqueEv() opaque(); } catch (int x) { - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) // CHECK: call i8* @__cxa_begin_catch diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp index 3e77f12fb5dc..2cee4f77e5d4 100644 --- a/test/CodeGenCXX/exceptions-seh.cpp +++ b/test/CodeGenCXX/exceptions-seh.cpp @@ -22,6 +22,7 @@ extern "C" void use_cxx() { // Make sure we use __CxxFrameHandler3 for C++ EH. // CXXEH-LABEL: define void @use_cxx() +// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) // CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) // CXXEH: invoke void @might_throw() // CXXEH: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] @@ -31,7 +32,7 @@ extern "C" void use_cxx() { // CXXEH: ret void // // CXXEH: [[lpad]] -// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CXXEH: landingpad { i8*, i32 } // CXXEH-NEXT: cleanup // CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) // CXXEH: br label %[[resume:[^ ]*]] @@ -59,6 +60,7 @@ extern "C" void use_seh() { // Make sure we use __C_specific_handler for SEH. // CHECK-LABEL: define void @use_seh() +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]] // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // @@ -66,7 +68,7 @@ extern "C" void use_seh() { // CHECK: br label %[[ret:[^ ]*]] // // CHECK: [[lpad]] -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK: landingpad { i8*, i32 } // CHECK-NEXT: catch i8* // // CHECK: br label %[[ret]] @@ -86,15 +88,17 @@ void use_seh_in_lambda() { } // CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() -// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CXXEH: landingpad { i8*, i32 } // NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() // NOCXX-NOT: invoke // NOCXX: ret void // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) +// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK: invoke void @might_throw() #[[NOINLINE]] -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK: landingpad { i8*, i32 } static int my_unique_global; @@ -114,10 +118,11 @@ void use_inline() { use_seh_in_inline_func(); } -// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat { +// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK: invoke void @might_throw() // -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK: landingpad { i8*, i32 } // CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_seh_in_inline_func@@" to i8*) // // CHECK: invoke void @might_throw() @@ -126,7 +131,7 @@ void use_inline() { // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]]) // CHECK: ret void // -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) // CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]]) diff --git a/test/CodeGenCXX/init-invariant.cpp b/test/CodeGenCXX/init-invariant.cpp index 45816b28fb65..8af4ae6fde46 100644 --- a/test/CodeGenCXX/init-invariant.cpp +++ b/test/CodeGenCXX/init-invariant.cpp @@ -41,13 +41,13 @@ void e() { static const A a = A(); } -// CHECK: call void @_ZN1AC1Ev({{.*}}* @a) +// CHECK: call void @_ZN1AC1Ev({{.*}}* nonnull @a) // CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @a to i8*)) -// CHECK: call void @_ZN1BC1Ev({{.*}}* @b) +// CHECK: call void @_ZN1BC1Ev({{.*}}* nonnull @b) // CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @b to i8*)) -// CHECK: call void @_ZN1CC1Ev({{.*}}* @c) +// CHECK: call void @_ZN1CC1Ev({{.*}}* nonnull @c) // CHECK-NOT: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @c to i8*)) // CHECK: call i32 @_Z1fv( @@ -55,6 +55,6 @@ void e() { // CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @d to i8*)) // CHECK-LABEL: define void @_Z1ev( -// CHECK: call void @_ZN1AC1Ev(%struct.A* @_ZZ1evE1a) +// CHECK: call void @_ZN1AC1Ev(%struct.A* nonnull @_ZZ1evE1a) // CHECK: call {{.*}}@llvm.invariant.start(i64 4, i8* bitcast ({{.*}} @_ZZ1evE1a to i8*)) // CHECK-NOT: llvm.invariant.end diff --git a/test/CodeGenCXX/mangle-long-double.cpp b/test/CodeGenCXX/mangle-long-double.cpp new file mode 100644 index 000000000000..e248c474a2e7 --- /dev/null +++ b/test/CodeGenCXX/mangle-long-double.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-LINUX +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-LINUX +// RUN: %clang_cc1 -triple powerpc64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-DARWIN +// RUN: %clang_cc1 -triple powerpc-apple-darwin9 %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-DARWIN +// RUN: %clang_cc1 -triple s390x-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=S390X-LINUX + +void f(long double) {} +// POWER64-LINUX: _Z1fg +// POWER-LINUX: _Z1fg +// POWER64-DARWIN: _Z1fe +// POWER-DARWIN: _Z1fe +// S390X-LINUX: _Z1fg diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index c12ceae131a6..8cb4a1f8bd24 100755 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -119,7 +119,7 @@ void (UnspecSingle::*us_f_mp)() = &UnspecSingle::foo; // CHECK: @"\01?v_f_mp@Const@@3P8Virtual@@AEXXZQ2@" = // CHECK: global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4 // CHECK: @"\01?u_f_mp@Const@@3P8Unspecified@@AEXXZQ2@" = -// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 4 +// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4 // CHECK: @"\01?us_f_mp@Const@@3P8UnspecSingle@@AEXXZQ2@" = // CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4 } @@ -191,11 +191,11 @@ void EmitNonVirtualMemberPointers() { // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, // CHECK: { i8*, i32, i32 }* %{{.*}}, align 4 // CHECK: store { i8*, i32, i32, i32 } -// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, +// CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, // CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 // CHECK: store { i8*, i32, i32, i32 } // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@UnspecWithVBPtr@@QAEXXZ" to i8*), -// CHECK: i32 0, i32 4, i32 0 }, +// CHECK: i32 0, i32 0, i32 0 }, // CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 // CHECK: ret void // CHECK: } @@ -678,6 +678,17 @@ static_assert(sizeof(int A::*) == 12, ""); // CHECK-LABEL: define void @"\01?test@pr20007_pragma2@@YAXXZ" } +namespace pr23823 { +struct Base { void Method(); }; +struct Child : Base {}; +void use(void (Child::*const &)()); +void f() { use(&Child::Method); } +#pragma pointers_to_members(full_generality, virtual_inheritance) +static_assert(sizeof(int Base::*) == 4, ""); +static_assert(sizeof(int Child::*) == 4, ""); +#pragma pointers_to_members(best_case) +} + namespace pr19987 { template <typename T> struct S { diff --git a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp index 5f6849dde038..89a62c2cb390 100644 --- a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp +++ b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp @@ -17,6 +17,7 @@ struct S { // CHECK-DAG: @"\01?$TSS0@?1??h@@YAAAUS@@_N@Z" = linkonce_odr global i32 0 // CHECK-LABEL: define {{.*}} @"\01?f@@YAAAUS@@XZ"() +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) extern inline S &f() { static thread_local S s; // CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" @@ -38,7 +39,7 @@ extern inline S &f() { // CHECK-NEXT: ret %struct.S* @"\01?s@?1??f@@YAAAUS@@XZ@4U2@A" // CHECK: [[lpad:.*]]: -// CHECK-NEXT: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CHECK-NEXT: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" // CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], -2 diff --git a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp index f6f75835c658..af930c84720b 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32 -// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64 +// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32 +// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64 struct S { int x, y, z; @@ -13,12 +13,15 @@ struct U { U(const U &); }; +struct B; + struct C { virtual void foo(); virtual int bar(int, double); virtual S baz(int); virtual S qux(U); virtual void thud(...); + virtual void (B::*plugh())(); }; namespace { @@ -47,6 +50,8 @@ void f() { void (C::*ptr6)(...); ptr6 = &C::thud; + auto ptr7 = &C::plugh; + // CHECK32-LABEL: define void @"\01?f@@YAXXZ"() // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr @@ -167,4 +172,18 @@ void f() { // CHECK64: ret void // CHECK64: } +// CHECK32: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BBE@AE"(%struct.C* %this, ...) {{.*}} comdat align 2 { +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: ret void +// CHECK32: } + +// CHECK64: define linkonce_odr void @"\01??_9C@@$BCI@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 { +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: ret void +// CHECK64: } + // CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}} diff --git a/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp b/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp index 6d42b8504abf..97ab1996c8bc 100644 --- a/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp +++ b/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp @@ -1,11 +1,15 @@ -// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm-only -verify - -// We reject this because LLVM doesn't forward the second regparm through the -// thunk. +// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s struct A { - virtual void __fastcall f(int a, int b); // expected-error {{cannot compile this pointer to fastcall virtual member function yet}} + virtual void __fastcall f(int a, int b); }; void (__fastcall A::*doit())(int, int) { return &A::f; } + +// CHECK: define linkonce_odr x86_fastcallcc void @"\01??_9A@@$BA@AI"(%struct.A* inreg %this, ...) {{.*}} comdat align 2 { +// CHECK: [[VPTR:%.*]] = getelementptr inbounds void (%struct.A*, ...)*, void (%struct.A*, ...)** %{{.*}}, i64 0 +// CHECK: [[CALLEE:%.*]] = load void (%struct.A*, ...)*, void (%struct.A*, ...)** [[VPTR]] +// CHECK: musttail call x86_fastcallcc void (%struct.A*, ...) [[CALLEE]](%struct.A* inreg %{{.*}}, ...) +// CHECK: ret void +// CHECK: } diff --git a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp index bacddb2936f4..9025f877c551 100644 --- a/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp +++ b/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp @@ -16,9 +16,11 @@ extern "C" void test() { } // X64: define void @test() +// X64-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) // X64: invoke void @foo() -// X64: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) +// X64: landingpad { i8*, i32 } // X86: define void @test() +// X86-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // X86: invoke void @foo() -// X86: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// X86: landingpad { i8*, i32 } diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index f4ed7cd9f6be..8744d141dddc 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -44,6 +44,7 @@ X test1(bool B) { // CHECK-LABEL: define void @_Z5test2b // CHECK-EH-LABEL: define void @_Z5test2b +// CHECK-EH-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) X test2(bool B) { // No NRVO. @@ -82,7 +83,7 @@ X test2(bool B) { // -> %cleanup, %lpad1 // %lpad: landing pad for ctor of 'y', dtor of 'y' - // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } // CHECK-EH-NEXT: cleanup // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 @@ -116,7 +117,7 @@ X test2(bool B) { // CHECK-EH: resume { i8*, i32 } // %terminate.lpad: terminate landing pad. - // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 } // CHECK-EH-NEXT: catch i8* null // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0 // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]] @@ -178,9 +179,9 @@ X test6() { // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0 // CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* [[PTR]]) - // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) - // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]]) - // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull dereferenceable({{[0-9]+}}) [[A]]) + // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]]) // CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* [[PTR]]) // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp index 01e289450d76..d135149592a1 100644 --- a/test/CodeGenCXX/partial-destruction.cpp +++ b/test/CodeGenCXX/partial-destruction.cpp @@ -12,6 +12,7 @@ namespace test0 { opaque(); } // CHECK-LABEL: define void @_ZN5test04testEv() + // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK: [[AS:%.*]] = alloca [10 x [[A:%.*]]], align // CHECK-NEXT: [[ENDVAR:%.*]] = alloca [[A]]* // CHECK-NEXT: [[EXN:%.*]] = alloca i8* @@ -50,7 +51,7 @@ namespace test0 { // CHECK: ret void // Partial destroy for initialization. - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: [[PARTIAL_END:%.*]] = load [[A]]*, [[A]]** [[ENDVAR]] // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]] @@ -62,7 +63,7 @@ namespace test0 { // CHECK-NEXT: br i1 [[T0]], // Primary EH destructor. - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i32 0, i32 0 // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E0]], i64 10 @@ -72,7 +73,7 @@ namespace test0 { // FIXME: There's some really bad block ordering here which causes // the partial destroy for the primary normal destructor to fall // within the primary EH destructor. - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]] // CHECK-NEXT: br i1 [[T0]] @@ -99,6 +100,7 @@ namespace test1 { B v = { 5, 6, 7, 8 }; } // CHECK-LABEL: define void @_ZN5test14testEv() + // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4 // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 @@ -114,9 +116,9 @@ namespace test1 { // CHECK-NEXT: ret void // FIXME: again, the block ordering is pretty bad here - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]]) // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[X]]) @@ -129,6 +131,7 @@ namespace test2 { A v[4][7]; // CHECK-LABEL: define void @_ZN5test24testEv() + // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK: [[V:%.*]] = alloca [4 x [7 x [[A:%.*]]]], align 1 // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 @@ -144,7 +147,7 @@ namespace test2 { // CHECK-NEXT: br i1 [[DONE]], // Partial destruction landing pad. - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]] // CHECK-NEXT: br i1 [[EMPTY]], diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp new file mode 100644 index 000000000000..d12e41274918 --- /dev/null +++ b/test/CodeGenCXX/pragma-loop-safety.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s + +// Verify assume_safety vectorization is recognized. +void vectorize_test(int *List, int Length) { +// CHECK: define {{.*}} @_Z14vectorize_testPii +// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID:[0-9]+]] +// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] +// CHECK-NEXT: [[CMP1:.+]] = icmp slt i32[[LOAD1_IV]],[[LOAD1_LEN]] +// CHECK-NEXT: br i1[[CMP1]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]], !llvm.loop ![[LOOP1_HINTS:[0-9]+]] +#pragma clang loop vectorize(assume_safety) + for (int i = 0; i < Length; i++) { + // CHECK: [[LOOP1_BODY]] + // CHECK-NEXT: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] + // CHECK-NEXT: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2 + // CHECK-NEXT: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] + // CHECK-NEXT: [[INDEX1:.+]] = sext i32[[SIV1]] to i64 + // CHECK-NEXT: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] + // CHECK-NEXT: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]] + // CHECK-NEXT: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] + List[i] = i * 2; + } + // CHECK: [[LOOP1_END]] +} + +// Verify assume_safety interleaving is recognized. +void interleave_test(int *List, int Length) { +// CHECK: define {{.*}} @_Z15interleave_testPii +// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID:[0-9]+]] +// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] +// CHECK-NEXT: [[CMP2:.+]] = icmp slt i32[[LOAD2_IV]],[[LOAD2_LEN]] +// CHECK-NEXT: br i1[[CMP2]], label %[[LOOP2_BODY:[^,]+]], label %[[LOOP2_END:[^,]+]], !llvm.loop ![[LOOP2_HINTS:[0-9]+]] +#pragma clang loop interleave(assume_safety) + for (int i = 0; i < Length; i++) { + // CHECK: [[LOOP2_BODY]] + // CHECK-NEXT: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] + // CHECK-NEXT: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2 + // CHECK-NEXT: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] + // CHECK-NEXT: [[INDEX2:.+]] = sext i32[[SIV2]] to i64 + // CHECK-NEXT: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] + // CHECK-NEXT: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]] + // CHECK-NEXT: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] + List[i] = i * 2; + } + // CHECK: [[LOOP2_END]] +} + +// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTENABLE_1:.*]]} +// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true} +// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[INTENABLE_1:.*]]} diff --git a/test/CodeGenCXX/redefine_extname.cpp b/test/CodeGenCXX/redefine_extname.cpp new file mode 100644 index 000000000000..2b6b703a1b8f --- /dev/null +++ b/test/CodeGenCXX/redefine_extname.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s + +extern "C" { + struct statvfs64 { + int f; + }; +#pragma redefine_extname statvfs64 statvfs + int statvfs64(struct statvfs64 *); +} + +void foo() { + struct statvfs64 st; + statvfs64(&st); +// Check that even if there is a structure with redefined name before the +// pragma, subsequent function name redefined properly. PR5172, Comment 11. +// CHECK: call i32 @statvfs(%struct.statvfs64* %st) +} + diff --git a/test/CodeGenCXX/stack-reuse.cpp b/test/CodeGenCXX/stack-reuse.cpp index a975f30a048a..473a57cda27d 100644 --- a/test/CodeGenCXX/stack-reuse.cpp +++ b/test/CodeGenCXX/stack-reuse.cpp @@ -134,8 +134,8 @@ int large_combiner_test(S_large s) { // CHECK-LABEL: define i32 @large_combiner_test // CHECK: [[T1:%.*]] = alloca %struct.Combiner // CHECK: [[T2:%.*]] = alloca %struct.Combiner -// CHECK: [[T3:%.*]] = call %struct.Combiner* @_ZN8CombinerC1E7S_large(%struct.Combiner* [[T1]], [9 x i32] %s.coerce) -// CHECK: call void @_ZN8Combiner1fEv(%struct.Combiner* sret [[T2]], %struct.Combiner* [[T1]]) +// CHECK: [[T3:%.*]] = call %struct.Combiner* @_ZN8CombinerC1E7S_large(%struct.Combiner* nonnull [[T1]], [9 x i32] %s.coerce) +// CHECK: call void @_ZN8Combiner1fEv(%struct.Combiner* nonnull sret [[T2]], %struct.Combiner* nonnull [[T1]]) // CHECK: [[T4:%.*]] = getelementptr inbounds %struct.Combiner, %struct.Combiner* [[T2]], i32 0, i32 0, i32 0, i32 0 // CHECK: [[T5:%.*]] = load i32, i32* [[T4]] // CHECK: ret i32 [[T5]] diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp index 70decc98a109..41325fa64fc5 100644 --- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp +++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp @@ -8,6 +8,7 @@ struct X { struct Y { }; // CHECK-LABEL: define void @_Z1fv +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) void f() { // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ1fvE1x) // CHECK: invoke void @_ZN1XC1Ev @@ -21,7 +22,7 @@ void f() { throw Y(); // Finally, the landing pad. - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK: cleanup // CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x) // CHECK: resume { i8*, i32 } diff --git a/test/CodeGenCXX/typeid.cpp b/test/CodeGenCXX/typeid.cpp index 9d212905e614..364f058c5b70 100644 --- a/test/CodeGenCXX/typeid.cpp +++ b/test/CodeGenCXX/typeid.cpp @@ -31,13 +31,14 @@ const std::type_info &a_ti = typeid(a); const std::type_info &A10_c_ti = typeid(char const[10]); // CHECK-LABEL: define i8* @_ZN5Test11fEv +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) const char *f() { try { // CHECK: br i1 // CHECK: invoke void @__cxa_bad_typeid() [[NR:#[0-9]+]] return typeid(*static_cast<A *>(0)).name(); } catch (...) { - // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: catch i8* null } diff --git a/test/CodeGenCXX/windows-itanium-exceptions.cpp b/test/CodeGenCXX/windows-itanium-exceptions.cpp index 3694d2c81371..b2c8707efc06 100644 --- a/test/CodeGenCXX/windows-itanium-exceptions.cpp +++ b/test/CodeGenCXX/windows-itanium-exceptions.cpp @@ -20,7 +20,8 @@ void attempt() { // CHECK: unreachable // CHECK: } -// CHECK: define {{.*}}void @_Z7attemptv() {{.*}} { +// CHECK: define {{.*}}void @_Z7attemptv() +// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK: %exn.slot = alloca i8* // CHECK: %ehselector.slot = alloca i32 // CHECK: invoke {{.*}}void @_Z6exceptv() @@ -28,7 +29,7 @@ void attempt() { // CHECK: invoke.cont: // CHECK: br label %try.cont // CHECK: lpad: -// CHECK: %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK: %0 = landingpad { i8*, i32 } // CHECK: catch i8* null // CHECK: %1 = extractvalue { i8*, i32 } %0, 0 // CHECK: store i8* %1, i8** %exn.slot |