Author: Yanzuo Liu Date: 2025-05-14T10:25:01+02:00 New Revision: 86ba681e286d0a377830d2cbbc5e58bb5fad442c
URL: https://github.com/llvm/llvm-project/commit/86ba681e286d0a377830d2cbbc5e58bb5fad442c DIFF: https://github.com/llvm/llvm-project/commit/86ba681e286d0a377830d2cbbc5e58bb5fad442c.diff LOG: [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 Added: clang/test/SemaCXX/libstdcxx_format_kind_hack.cpp Modified: clang/lib/Sema/SemaTemplate.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 486414ea84861..e306da357ca86 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<typename _Rg> + constexpr auto format_kind = + __primary_template_not_defined( + format_kind<_Rg> + ); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits