diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 7940340064eda..33fe8204ea5fb 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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), diff --git a/clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp b/clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp new file mode 100644 index 0000000000000..35611c870b8d1 --- /dev/null +++ b/clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp @@ -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 + constexpr auto format_kind = + __primary_template_not_defined( + format_kind<_Rg> + ); +}