summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-12-26 20:07:52 +0000
committerReid Kleckner <rnk@google.com>2018-12-26 20:07:52 +0000
commit3ab5a9cd1c826b627d6bcc775df824f637dd9e17 (patch)
tree59fe307150248229891d860782766f4f68a64eda
parent56c5343e5a9fe03533251a623006c3d5c79db547 (diff)
downloadbcm5719-llvm-3ab5a9cd1c826b627d6bcc775df824f637dd9e17.tar.gz
bcm5719-llvm-3ab5a9cd1c826b627d6bcc775df824f637dd9e17.zip
[MS] Mangle return adjusting thunks with the public access specifier
MSVC does this, so we should too. Fixes PR40138 llvm-svn: 350071
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp18
-rw-r--r--clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp29
2 files changed, 41 insertions, 6 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index caa3af598db..92e9679e49a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2939,14 +2939,14 @@ void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D,
// <vtordisp-shift> ::= <offset-to-vtordisp>
// <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>
// <offset-to-vtordisp>
-static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
+static void mangleThunkThisAdjustment(AccessSpecifier AS,
const ThisAdjustment &Adjustment,
MicrosoftCXXNameMangler &Mangler,
raw_ostream &Out) {
if (!Adjustment.Virtual.isEmpty()) {
Out << '$';
char AccessSpec;
- switch (MD->getAccess()) {
+ switch (AS) {
case AS_none:
llvm_unreachable("Unsupported access specifier");
case AS_private:
@@ -2974,7 +2974,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
}
} else if (Adjustment.NonVirtual != 0) {
- switch (MD->getAccess()) {
+ switch (AS) {
case AS_none:
llvm_unreachable("Unsupported access specifier");
case AS_private:
@@ -2988,7 +2988,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
}
Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
} else {
- switch (MD->getAccess()) {
+ switch (AS) {
case AS_none:
llvm_unreachable("Unsupported access specifier");
case AS_private:
@@ -3019,7 +3019,13 @@ void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
MicrosoftCXXNameMangler Mangler(*this, MHO);
Mangler.getStream() << '?';
Mangler.mangleName(MD);
- mangleThunkThisAdjustment(MD, Thunk.This, Mangler, MHO);
+
+ // Usually the thunk uses the access specifier of the new method, but if this
+ // is a covariant return thunk, then MSVC always uses the public access
+ // specifier, and we do the same.
+ AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;
+ mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);
+
if (!Thunk.Return.isEmpty())
assert(Thunk.Method != nullptr &&
"Thunk info should hold the overridee decl");
@@ -3040,7 +3046,7 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
Mangler.getStream() << "??_E";
Mangler.mangleName(DD->getParent());
- mangleThunkThisAdjustment(DD, Adjustment, Mangler, MHO);
+ mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);
Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
}
diff --git a/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp b/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
new file mode 100644
index 00000000000..47b1a38ffe1
--- /dev/null
+++ b/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fno-rtti-data -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK
+
+namespace t1 {
+struct A {
+public:
+ virtual ~A();
+ virtual A *f();
+};
+struct B {
+public:
+ virtual ~B();
+
+private:
+ virtual B *f();
+};
+struct C : A, B {
+ virtual ~C();
+
+protected:
+ virtual C *f();
+};
+C c;
+}
+// Main external C::f impl:
+// CHECK-DAG: "?f@C@t1@@MEAAPEAU12@XZ"
+// New slot in C's vftable for B, returns C* directly:
+// CHECK-DAG: "?f@C@t1@@O7EAAPEAU12@XZ"
+// Return-adjusting thunk in C's vftable for B:
+// CHECK-DAG: "?f@C@t1@@W7EAAPEAUB@2@XZ"
OpenPOWER on IntegriCloud