-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling for pointer types #92477
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Max Winkler (MaxEW707) Changeshttps://godbolt.org/z/G1K8Wszn9 for reference. Starting with MSVC 1920+, VS2019, C++17 auto NTTP now adds Here is a small example. The godbolt has more thorough examples.
Full diff: https://github.com/llvm/llvm-project/pull/92477.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a3c8e4141ca54..80ea74ed295f9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -79,6 +79,13 @@ ABI Changes in This Version
- Fixed Microsoft calling convention when returning classes that have a deleted
copy assignment operator. Such a class should be returned indirectly.
+- Fixed Microsoft name mangling for auto non-type template arguments of pointer
+ type for MSVC 1920+. This change resolves incompatibilities with code compiled
+ by MSVC 1920+ but will introduce incompatibilities with code compiled by
+ earlier versions of Clang unless such code is built with the compiler option
+ `-fms-compatibility-version=19.14` to imitate the MSVC 1914 mangling behavior.
+
+
AST Dumping Potentially Breaking Changes
----------------------------------------
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 36d611750ca48..627c4511f2816 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -372,6 +372,11 @@ class MicrosoftCXXNameMangler {
void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
StringRef Prefix = "$");
+ void mangleFunctionPointer(const FunctionDecl *FD,
+ const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType);
+ void mangleVarDecl(const VarDecl *VD, const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType);
void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,
const CXXMethodDecl *MD);
void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
@@ -799,6 +804,50 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
mangleNumber(VBTableOffset);
}
+void MicrosoftCXXNameMangler::mangleFunctionPointer(
+ const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType) {
+ // <func-ptr> ::= $1? <mangled-name>
+ // <func-ptr> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 1? <mangled-name>
+ Out << '$';
+
+ if (getASTContext().getLangOpts().isCompatibleWithMSVC(
+ LangOptions::MSVC2019) &&
+ PD && PD->getType()->getTypeClass() == Type::Auto &&
+ !TemplateArgType.isNull()) {
+ Out << "M";
+ mangleType(TemplateArgType, SourceRange(), QMM_Drop);
+ }
+
+ Out << "1?";
+ mangleName(FD);
+ mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
+}
+
+void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,
+ const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType) {
+ // <var-ptr> ::= $1? <mangled-name>
+ // <var-ptr> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 1? <mangled-name>
+ Out << '$';
+
+ if (getASTContext().getLangOpts().isCompatibleWithMSVC(
+ LangOptions::MSVC2019) &&
+ PD && PD->getType()->getTypeClass() == Type::Auto &&
+ !TemplateArgType.isNull()) {
+ Out << "M";
+ mangleType(TemplateArgType, SourceRange(), QMM_Drop);
+ }
+
+ Out << "1?";
+ mangleName(VD);
+ mangleVariableEncoding(VD);
+}
+
void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
// <nttp-class-member-function-pointer> ::= <member-function-pointer>
@@ -1552,6 +1601,9 @@ void MicrosoftCXXNameMangler::mangleIntegerLiteral(
const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
QualType TemplateArgType) {
// <integer-literal> ::= $0 <number>
+ // <integer-literal> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 0 <number>
Out << "$";
// Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
@@ -1629,8 +1681,11 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
// ::= <member-data-pointer>
// ::= <member-function-pointer>
// ::= $ <constant-value>
+ // ::= $ <auto-nttp-constant-value>
// ::= <template-args>
//
+ // <auto-nttp-constant-value> ::= M <type> <constant-value>
+ //
// <constant-value> ::= 0 <number> # integer
// ::= 1 <mangled-name> # address of D
// ::= 2 <type> <typed-constant-value>* @ # struct
@@ -1678,15 +1733,17 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
mangleMemberFunctionPointer(
MD->getParent()->getMostRecentNonInjectedDecl(), MD);
} else {
- Out << "$1?";
- mangleName(FD);
- mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
+ mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
}
} else if (TA.getParamTypeForDecl()->isRecordType()) {
Out << "$";
auto *TPO = cast<TemplateParamObjectDecl>(ND);
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
TPO->getValue(), TplArgKind::ClassNTTP);
+ } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
} else {
mangle(ND, "$1?");
}
diff --git a/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp b/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
index c17f5f5e4477f..ff5395cea75eb 100644
--- a/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
@@ -18,6 +18,12 @@ auto AutoFunc() {
return a;
}
+int Func();
+int Func2();
+
+int i;
+int j;
+
void template_mangling() {
AutoFunc<1>();
// AFTER: call {{.*}} @"??$AutoFunc@$MH00@@YA?A?<auto>@@XZ"
@@ -44,4 +50,29 @@ void template_mangling() {
AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2;
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MK00$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$00$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+
+ AutoFunc<&i>();
+ // AFTER: call {{.*}} @"??$AutoFunc@$MPEAH1?i@@3HA@@YA?A?<auto>@@XZ"
+ // BEFORE: call {{.*}} @"??$AutoFunc@$1?i@@3HA@@YA?A?<auto>@@XZ"
+
+ AutoParmTemplate<&i> auto_int_ptr;
+ // AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MPEAH1?i@@3HA@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?i@@3HA@@QEAA@XZ"
+
+ AutoParmsTemplate<&i, &j> auto_int_ptrs;
+ // AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?i@@3HA$1?j@@3HA@@QEAA@XZ"
+
+ AutoFunc<&Func>();
+ // AFTER: call {{.*}} @"??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
+ // BEFORE: call {{.*}} @"??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
+
+ AutoParmTemplate<&Func> auto_func_ptr;
+ // AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MP6AHXZ1?Func@@YAHXZ@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?Func@@YAHXZ@@QEAA@XZ"
+
+ AutoParmsTemplate<&Func, &Func2> auto_func_ptrs;
+ // AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?Func@@YAHXZ$1?Func2@@YAHXZ@@QEAA@XZ"
+
}
|
76f732d
to
940187a
Compare
https://godbolt.org/z/G1K8Wszn9 for reference.
Starting with MSVC 1920+, VS2019, C++17 auto NTTP now adds
M <type>
to the mangled name to avoid name collisions with different deduced types.This PR fixes pointers. Pointers to members will be fixed in an upcoming PR.
Here is a small example. The godbolt has more thorough examples.