r350071 - [MS] Mangle return adjusting thunks with the public access specifier

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 26 12:07:52 PST 2018


Author: rnk
Date: Wed Dec 26 12:07:52 2018
New Revision: 350071

URL: http://llvm.org/viewvc/llvm-project?rev=350071&view=rev
Log:
[MS] Mangle return adjusting thunks with the public access specifier

MSVC does this, so we should too.

Fixes PR40138

Added:
    cfe/trunk/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=350071&r1=350070&r2=350071&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Wed Dec 26 12:07:52 2018
@@ -2939,14 +2939,14 @@ void MicrosoftMangleContextImpl::mangleC
 // <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(co
       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(co
     }
     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::mangleT
   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::mangleC
   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);
 }
 

Added: cfe/trunk/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp?rev=350071&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp Wed Dec 26 12:07:52 2018
@@ -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 at C@t1@@MEAAPEAU12 at XZ"
+// New slot in C's vftable for B, returns C* directly:
+// CHECK-DAG: "?f at C@t1@@O7EAAPEAU12 at XZ"
+// Return-adjusting thunk in C's vftable for B:
+// CHECK-DAG: "?f at C@t1@@W7EAAPEAUB at 2@XZ"




More information about the cfe-commits mailing list