diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 623a4b3c18bb1..1ae35e6881d2f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -47,6 +47,12 @@ C++ Specific Potentially Breaking Changes ABI Changes in This Version --------------------------- +- Fixed Microsoft name mangling of implicitly defined variables used for thread + safe static initialization of static local variables. This change resolves + incompatibilities with code compiled by MSVC but might introduce + incompatibilities with code compiled by earlier versions of Clang when an + inline member function that contains a static local variable with a dynamic + initializer is declared with ``__declspec(dllimport)``. (#GH83616). AST Dumping Potentially Breaking Changes ---------------------------------------- diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index b272a546573a3..aa26bb7ed46f4 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -390,6 +390,7 @@ class MicrosoftCXXNameMangler { const FunctionDecl *D = nullptr, bool ForceThisQuals = false, bool MangleExceptionSpec = true); + void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); private: @@ -408,7 +409,6 @@ class MicrosoftCXXNameMangler { mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName()); } void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name); - void mangleSourceName(StringRef Name); void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); void mangleCXXDtorType(CXXDtorType T); void mangleQualifiers(Qualifiers Quals, bool IsMember); @@ -3920,7 +3920,8 @@ void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable( msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); - Mangler.getStream() << "?$TSS" << GuardNum << '@'; + Mangler.getStream() << "?"; + Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum)); Mangler.mangleNestedName(VD); Mangler.getStream() << "@4HA"; } diff --git a/clang/test/CodeGenCXX/mangle-ms-back-references.cpp b/clang/test/CodeGenCXX/mangle-ms-back-references.cpp index cb95c100b3d22..b27a9c5acacb7 100644 --- a/clang/test/CodeGenCXX/mangle-ms-back-references.cpp +++ b/clang/test/CodeGenCXX/mangle-ms-back-references.cpp @@ -83,3 +83,20 @@ class H; void ManyParams(T01 &, T02 &, T03 &, T04 &, T05 &, T06 &, T07 &, T08 &, T09 &, T10 &, H &, H &) {} // CHECK: "?ManyParams@@YAXAAVT01@@AAVT02@@AAVT03@@AAVT04@@AAVT05@@AAVT06@@AAVT07@@AAVT08@@AAVT09@@AAVT10@@AAV?$H@VT11@@@@AAV?$H@VT11@@@@@Z" + +namespace NS { +// The name "TSS0" for the name of the class below has been specifically +// chosen to ensure that back reference lookup does not match against the +// implicitly generated "$TSS0" name of the thread safe static initialization +// variable. +struct __declspec(dllexport) TSS0 { + static TSS0& get(); + __forceinline static TSS0& singleton() { + static TSS0& lsv = get(); + return lsv; + } +}; +} +// CHECK: "?singleton@TSS0@NS@@SAAAU12@XZ" +// CHECK: "?lsv@?1??singleton@TSS0@NS@@SAAAU23@XZ@4AAU23@A" +// CHECK: "?$TSS0@?1??singleton@TSS0@NS@@SAAAU23@XZ@4HA"