summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-04-11 19:36:51 +0000
committerTom Stellard <thomas.stellard@amd.com>2014-04-11 19:36:51 +0000
commitf0092f48ab86f842825113a8104f051ee2a4b63b (patch)
treef86d54f8604e5876932d5f18aa23cae00337d1a9
parent2c2b1619b74b7ae753d9adcdffb8ee22e4121e90 (diff)
downloadllvm-f0092f48ab86f842825113a8104f051ee2a4b63b.tar.gz
Merging r203007:
------------------------------------------------------------------------ r203007 | rafael.espindola | 2014-03-05 16:04:41 -0500 (Wed, 05 Mar 2014) | 4 lines Don't produce an alias between destructors with different calling conventions. Fixes pr19007. ------------------------------------------------------------------------ llvm-svn: 206059
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp6
-rw-r--r--clang/test/CodeGenCXX/ctor-dtor-alias.cpp20
2 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index cfb2d6291b8a..2f8a17afbcd1 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -92,7 +92,13 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero())
return true;
+ // Give up if the calling conventions don't match. We could update the call,
+ // but it is probably not worth it.
const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
+ if (BaseD->getType()->getAs<FunctionType>()->getCallConv() !=
+ D->getType()->getAs<FunctionType>()->getCallConv())
+ return true;
+
return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
GlobalDecl(BaseD, Dtor_Base),
false);
diff --git a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
index 235d1650dec9..d8d1fab7cef3 100644
--- a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
-// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
// RUN: %clang_cc1 -cc1 -triple x86_64--netbsd -emit-llvm \
// RUN: -mconstructor-aliases -O2 %s -o - | FileCheck --check-prefix=CHECK-RAUW %s
@@ -133,6 +133,22 @@ namespace test8 {
zed foo;
}
+namespace test9 {
+struct foo {
+ __attribute__((stdcall)) ~foo() {
+ }
+};
+
+struct bar : public foo {};
+
+void zed() {
+ // Test that we produce a call to bar's destructor. We used to call foo's, but
+ // it has a different calling conversion.
+ // CHECK-DAG: call void @_ZN5test93barD2Ev
+ bar ptr;
+}
+}
+
// CHECK-RAUW: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
// r194296 replaced C::~C with B::~B without emitting the later.