Skip to content

[clang][MSVC] Correct mangling of thread-safe static initialization variables. #85300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -408,7 +409,6 @@ class MicrosoftCXXNameMangler {
mangleUnqualifiedName(GD, cast<NamedDecl>(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);
Expand Down Expand Up @@ -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";
}
Expand Down
17 changes: 17 additions & 0 deletions clang/test/CodeGenCXX/mangle-ms-back-references.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,20 @@ class H;

void ManyParams(T01 &, T02 &, T03 &, T04 &, T05 &, T06 &, T07 &, T08 &, T09 &, T10 &, H<T11> &, H<T11> &) {}
// 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"