Skip to content

Commit 86ba681

Browse files
authored
[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
1 parent 3a81979 commit 86ba681

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

clang/lib/Sema/SemaTemplate.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -4353,6 +4353,38 @@ struct PartialSpecMatchResult {
43534353
VarTemplatePartialSpecializationDecl *Partial;
43544354
TemplateArgumentList *Args;
43554355
};
4356+
4357+
// HACK 2025-05-13: workaround std::format_kind since libstdc++ 15.1 (2025-04)
4358+
// See GH139067 / https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120190
4359+
static bool IsLibstdcxxStdFormatKind(Preprocessor &PP, VarDecl *Var) {
4360+
if (Var->getName() != "format_kind" ||
4361+
!Var->getDeclContext()->isStdNamespace())
4362+
return false;
4363+
4364+
MacroInfo *MacroGLIBCXX =
4365+
PP.getMacroInfo(PP.getIdentifierInfo("__GLIBCXX__"));
4366+
4367+
if (!MacroGLIBCXX || MacroGLIBCXX->getNumTokens() != 1)
4368+
return false;
4369+
4370+
const Token &RevisionDateTok = MacroGLIBCXX->getReplacementToken(0);
4371+
bool Invalid = false;
4372+
std::string RevisionDate = PP.getSpelling(RevisionDateTok, &Invalid);
4373+
StringRef FixDate = "30251231";
4374+
4375+
if (Invalid)
4376+
return false;
4377+
4378+
// The format of the revision date is in compressed ISO date format.
4379+
// See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html
4380+
// So we can use string comparison.
4381+
//
4382+
// Checking old versions of libstdc++ is not needed because 15.1 is the first
4383+
// release in which users can access std::format_kind.
4384+
//
4385+
// FIXME: Correct FixDate once the issue is fixed.
4386+
return RevisionDate.size() == 8 && RevisionDate <= FixDate;
4387+
}
43564388
} // end anonymous namespace
43574389

43584390
DeclResult
@@ -4384,6 +4416,8 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
43844416

43854417
if (VarDecl *Var = Template->getTemplatedDecl();
43864418
ParsingInitForAutoVars.count(Var) &&
4419+
// See comments on this function definition
4420+
!IsLibstdcxxStdFormatKind(PP, Var) &&
43874421
llvm::equal(
43884422
CTAI.CanonicalConverted,
43894423
Template->getTemplateParameters()->getInjectedTemplateArgs(Context),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
// Primary variable template std::format_kind is defined as followed since
6+
// libstdc++ 15.1, which triggers compilation error introduced by GH134522.
7+
// This file tests the workaround.
8+
9+
#define __GLIBCXX__ 20250513
10+
11+
namespace std {
12+
template<typename _Rg>
13+
constexpr auto format_kind =
14+
__primary_template_not_defined(
15+
format_kind<_Rg>
16+
);
17+
}

0 commit comments

Comments
 (0)