[clang] 86ba681 - [Clang][Sema] Disable checking invalid template id in initializer of primary variable template `std::format_kind` with libstdc++ (#139560)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 14 01:25:05 PDT 2025
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>
+ );
+}
More information about the cfe-commits
mailing list