[Clang][Sema] Disable checking invalid template id in initializer of primary variable template std::format_kind
with libstdc++ (#139560)
#134522 triggers compilation error with libstdc++, in which primary variable template `std::format_kind` is defined like ```cpp template <typename R> constexpr auto format_kind = __primary_template_not_defined( format_kind<R> ); ``` See #139067 or <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120190>. This PR disables checking template id in initializer of primary variable template `std::format_kind` in libstdc++ (by checking `__GLIBCXX__`). Fixes #139067
This commit is contained in:
parent
3a81979a31
commit
86ba681e28
@ -4353,6 +4353,38 @@ struct PartialSpecMatchResult {
|
||||
VarTemplatePartialSpecializationDecl *Partial;
|
||||
TemplateArgumentList *Args;
|
||||
};
|
||||
|
||||
// HACK 2025-05-13: workaround std::format_kind since libstdc++ 15.1 (2025-04)
|
||||
// See GH139067 / https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120190
|
||||
static bool IsLibstdcxxStdFormatKind(Preprocessor &PP, VarDecl *Var) {
|
||||
if (Var->getName() != "format_kind" ||
|
||||
!Var->getDeclContext()->isStdNamespace())
|
||||
return false;
|
||||
|
||||
MacroInfo *MacroGLIBCXX =
|
||||
PP.getMacroInfo(PP.getIdentifierInfo("__GLIBCXX__"));
|
||||
|
||||
if (!MacroGLIBCXX || MacroGLIBCXX->getNumTokens() != 1)
|
||||
return false;
|
||||
|
||||
const Token &RevisionDateTok = MacroGLIBCXX->getReplacementToken(0);
|
||||
bool Invalid = false;
|
||||
std::string RevisionDate = PP.getSpelling(RevisionDateTok, &Invalid);
|
||||
StringRef FixDate = "30251231";
|
||||
|
||||
if (Invalid)
|
||||
return false;
|
||||
|
||||
// The format of the revision date is in compressed ISO date format.
|
||||
// See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html
|
||||
// So we can use string comparison.
|
||||
//
|
||||
// Checking old versions of libstdc++ is not needed because 15.1 is the first
|
||||
// release in which users can access std::format_kind.
|
||||
//
|
||||
// FIXME: Correct FixDate once the issue is fixed.
|
||||
return RevisionDate.size() == 8 && RevisionDate <= FixDate;
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
DeclResult
|
||||
@ -4384,6 +4416,8 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
|
||||
|
||||
if (VarDecl *Var = Template->getTemplatedDecl();
|
||||
ParsingInitForAutoVars.count(Var) &&
|
||||
// See comments on this function definition
|
||||
!IsLibstdcxxStdFormatKind(PP, Var) &&
|
||||
llvm::equal(
|
||||
CTAI.CanonicalConverted,
|
||||
Template->getTemplateParameters()->getInjectedTemplateArgs(Context),
|
||||
|
17
clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp
Normal file
17
clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -verify %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
// Primary variable template std::format_kind is defined as followed since
|
||||
// libstdc++ 15.1, which triggers compilation error introduced by GH134522.
|
||||
// This file tests the workaround.
|
||||
|
||||
#define __GLIBCXX__ 20250513
|
||||
|
||||
namespace std {
|
||||
template<typename _Rg>
|
||||
constexpr auto format_kind =
|
||||
__primary_template_not_defined(
|
||||
format_kind<_Rg>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user