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@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" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits