Skip to content

Revert "[Clang] Improve infrastructure for libstdc++ workarounds" #142432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2025

Conversation

cor3ntin
Copy link
Contributor

@cor3ntin cor3ntin commented Jun 2, 2025

Reverts #141977

This causes CI failure that I am unable to reproduce.
https://lab.llvm.org/buildbot/#/builders/168/builds/12688

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 2, 2025

@llvm/pr-subscribers-clang

Author: cor3ntin (cor3ntin)

Changes

Reverts llvm/llvm-project#141977

This causes CI failure that I am unable to reproduce.
https://lab.llvm.org/buildbot/#/builders/168/builds/12688


Full diff: https://github.com/llvm/llvm-project/pull/142432.diff

10 Files Affected:

  • (modified) clang/include/clang/Lex/Preprocessor.h (-15)
  • (modified) clang/lib/Lex/PPExpressions.cpp (-46)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (-1)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (-3)
  • (modified) clang/lib/Sema/SemaInit.cpp (+2-5)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+22-3)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+11-13)
  • (modified) clang/test/SemaCXX/libstdcxx_common_type_hack.cpp (+1-1)
  • (modified) clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp (+1-1)
  • (modified) clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp (+9-9)
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index cab398ad4a865..f2dfd3a349b8b 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -129,12 +129,6 @@ enum class EmbedResult {
   Empty = 2,    // Corresponds to __STDC_EMBED_EMPTY__
 };
 
-struct CXXStandardLibraryVersionInfo {
-  enum Library { Unknown, LibStdCXX };
-  Library Lib;
-  unsigned Version;
-};
-
 /// Engages in a tight little dance with the lexer to efficiently
 /// preprocess tokens.
 ///
@@ -2712,15 +2706,6 @@ class Preprocessor {
     return IsFileLexer(CurLexer.get(), CurPPLexer);
   }
 
-  //===--------------------------------------------------------------------===//
-  // Standard Library Identification
-  std::optional<CXXStandardLibraryVersionInfo> CXXStandardLibraryVersion;
-
-public:
-  std::optional<unsigned> getStdLibCxxVersion();
-  bool NeedsStdLibCxxWorkaroundBefore(unsigned FixedVersion);
-
-private:
   //===--------------------------------------------------------------------===//
   // Caching stuff.
   void CachingLex(Token &Result);
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 118d4ae6791d1..cf7e32bee2e71 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -979,49 +979,3 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
   return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,
                                      CheckForEoD);
 }
-
-static std::optional<CXXStandardLibraryVersionInfo>
-getCXXStandardLibraryVersion(Preprocessor &PP, StringRef MacroName,
-                             CXXStandardLibraryVersionInfo::Library Lib) {
-  MacroInfo *Macro = PP.getMacroInfo(PP.getIdentifierInfo(MacroName));
-
-  if (!Macro || Macro->getNumTokens() != 1 || !Macro->isObjectLike())
-    return std::nullopt;
-
-  const Token &RevisionDateTok = Macro->getReplacementToken(0);
-
-  bool Invalid = false;
-  llvm::SmallVector<char, 10> Buffer;
-  llvm::StringRef RevisionDate =
-      PP.getSpelling(RevisionDateTok, Buffer, &Invalid);
-  if (!Invalid) {
-    unsigned Value;
-    // We don't use NumericParser to avoid diagnostics
-    if (!RevisionDate.consumeInteger(10, Value))
-      return CXXStandardLibraryVersionInfo{Lib, Value};
-  }
-  return CXXStandardLibraryVersionInfo{CXXStandardLibraryVersionInfo::Unknown,
-                                       0};
-}
-
-std::optional<unsigned> Preprocessor::getStdLibCxxVersion() {
-  if (!CXXStandardLibraryVersion)
-    CXXStandardLibraryVersion = getCXXStandardLibraryVersion(
-        *this, "__GLIBCXX__", CXXStandardLibraryVersionInfo::LibStdCXX);
-  if (!CXXStandardLibraryVersion)
-    return std::nullopt;
-
-  if (CXXStandardLibraryVersion->Lib ==
-      CXXStandardLibraryVersionInfo::LibStdCXX)
-    return CXXStandardLibraryVersion->Version;
-  return std::nullopt;
-}
-
-bool Preprocessor::NeedsStdLibCxxWorkaroundBefore(unsigned FixedVersion) {
-  assert(FixedVersion >= 2000'00'00 && FixedVersion <= 2100'00'00 &&
-         "invalid value for __GLIBCXX__");
-  std::optional<unsigned> Ver = getStdLibCxxVersion();
-  if (!Ver)
-    return false;
-  return *Ver < FixedVersion;
-}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 55e078f3180a2..4a735992cec68 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13198,7 +13198,6 @@ NamedDecl *Sema::BuildUsingDeclaration(
     if (getLangOpts().CPlusPlus14 && II && II->isStr("gets") &&
         CurContext->isStdNamespace() &&
         isa<TranslationUnitDecl>(LookupContext) &&
-        PP.NeedsStdLibCxxWorkaroundBefore(2016'12'21) &&
         getSourceManager().isInSystemHeader(UsingLoc))
       return nullptr;
     UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(),
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index c692f824da422..c83eab53891ca 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -18,7 +18,6 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include <optional>
@@ -45,8 +44,6 @@ static const FunctionProtoType *GetUnderlyingFunction(QualType T)
 bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) {
   auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
 
-  if (!getPreprocessor().NeedsStdLibCxxWorkaroundBefore(2016'04'27))
-    return false;
   // All the problem cases are member functions named "swap" within class
   // templates declared directly within namespace std or std::__debug or
   // std::__profile.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 5d870f07093ec..776cb022e6925 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -21,7 +21,6 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
@@ -642,10 +641,8 @@ ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc,
   // in that case. stlport does so too.
   // Look for std::__debug for libstdc++, and for std:: for stlport.
   // This is effectively a compiler-side implementation of LWG2193.
-  if (!InitSeq && EmptyInitList &&
-      InitSeq.getFailureKind() ==
-          InitializationSequence::FK_ExplicitConstructor &&
-      SemaRef.getPreprocessor().NeedsStdLibCxxWorkaroundBefore(2014'04'22)) {
+  if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
+          InitializationSequence::FK_ExplicitConstructor) {
     OverloadCandidateSet::iterator Best;
     OverloadingResult O =
         InitSeq.getFailedCandidateSet()
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1d8fea1d72008..10e7823542f0b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4444,8 +4444,16 @@ static bool IsLibstdcxxStdFormatKind(Preprocessor &PP, VarDecl *Var) {
       !Var->getDeclContext()->isStdNamespace())
     return false;
 
-  // Checking old versions of libstdc++ is not needed because 15.1 is the first
-  // release in which users can access std::format_kind.
+  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);
+
   // We can use 20250520 as the final date, see the following commits.
   // GCC releases/gcc-15 branch:
   // https://gcc.gnu.org/g:fedf81ef7b98e5c9ac899b8641bb670746c51205
@@ -4453,7 +4461,18 @@ static bool IsLibstdcxxStdFormatKind(Preprocessor &PP, VarDecl *Var) {
   // GCC master branch:
   // https://gcc.gnu.org/g:9361966d80f625c5accc25cbb439f0278dd8b278
   // https://gcc.gnu.org/g:c65725eccbabf3b9b5965f27fff2d3b9f6c75930
-  return PP.NeedsStdLibCxxWorkaroundBefore(2025'05'20);
+  StringRef FixDate = "20250520";
+
+  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.
+  return RevisionDate.size() == 8 && RevisionDate < FixDate;
 }
 } // end anonymous namespace
 
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index bcad815e1587f..0de569ebcfe2e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1448,19 +1448,17 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
   // happen to be processing that implementation, fake up the g++ ?:
   // semantics. See LWG issue 2141 for more information on the bug.  The bugs
   // are fixed in g++ and libstdc++ 4.9.0 (2014-04-22).
-  if (SemaRef.getPreprocessor().NeedsStdLibCxxWorkaroundBefore(2014'04'22)) {
-    const DecltypeType *DT = DI->getType()->getAs<DecltypeType>();
-    CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext());
-    if (DT && RD && isa<ConditionalOperator>(DT->getUnderlyingExpr()) &&
-        DT->isReferenceType() &&
-        RD->getEnclosingNamespaceContext() == SemaRef.getStdNamespace() &&
-        RD->getIdentifier() && RD->getIdentifier()->isStr("common_type") &&
-        D->getIdentifier() && D->getIdentifier()->isStr("type") &&
-        SemaRef.getSourceManager().isInSystemHeader(D->getBeginLoc()))
-      // Fold it to the (non-reference) type which g++ would have produced.
-      DI = SemaRef.Context.getTrivialTypeSourceInfo(
-          DI->getType().getNonReferenceType());
-  }
+  const DecltypeType *DT = DI->getType()->getAs<DecltypeType>();
+  CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext());
+  if (DT && RD && isa<ConditionalOperator>(DT->getUnderlyingExpr()) &&
+      DT->isReferenceType() &&
+      RD->getEnclosingNamespaceContext() == SemaRef.getStdNamespace() &&
+      RD->getIdentifier() && RD->getIdentifier()->isStr("common_type") &&
+      D->getIdentifier() && D->getIdentifier()->isStr("type") &&
+      SemaRef.getSourceManager().isInSystemHeader(D->getBeginLoc()))
+    // Fold it to the (non-reference) type which g++ would have produced.
+    DI = SemaRef.Context.getTrivialTypeSourceInfo(
+      DI->getType().getNonReferenceType());
 
   // Create the new typedef
   TypedefNameDecl *Typedef;
diff --git a/clang/test/SemaCXX/libstdcxx_common_type_hack.cpp b/clang/test/SemaCXX/libstdcxx_common_type_hack.cpp
index 0e7ba5d6ef0c9..e9cb22f9dabfa 100644
--- a/clang/test/SemaCXX/libstdcxx_common_type_hack.cpp
+++ b/clang/test/SemaCXX/libstdcxx_common_type_hack.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -D__GLIBCXX__=20100000L
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify
 
 // This is a test for an egregious hack in Clang that works around
 // an issue with GCC's <type_traits> implementation. std::common_type
diff --git a/clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp b/clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp
index c85af1b1cd567..f9e0a5c0a1f02 100644
--- a/clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp
+++ b/clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers -D__GLIBCXX__=20100000L %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s
 
 // libstdc++4.6 in debug mode has explicit default constructors.
 // stlport has this for all containers.
diff --git a/clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp b/clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
index 6b8ca4f740914..dff599b6d5b66 100644
--- a/clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
+++ b/clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
@@ -7,20 +7,20 @@
 // The same problem afflicts a bunch of other class templates. Those
 // affected are array, pair, priority_queue, stack, and queue.
 
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DPR28423
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=pair
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=priority_queue
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=stack
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=queue
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=queue
 //
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DNAMESPACE=__debug
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DNAMESPACE=__profile
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__debug
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__profile
 
 // MSVC's standard library uses a very similar pattern that relies on delayed
 // parsing of exception specifications.
 //
-// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DMSVC
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DMSVC
 
 #ifdef BE_THE_HEADER
 

Copy link

github-actions bot commented Jun 2, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- clang/include/clang/Lex/Preprocessor.h clang/lib/Lex/PPExpressions.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaInit.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaCXX/libstdcxx_common_type_hack.cpp clang/test/SemaCXX/libstdcxx_explicit_init_list_hack.cpp clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
View the diff from clang-format here.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 776cb022e..e06703f02 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -641,7 +641,8 @@ ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc,
   // in that case. stlport does so too.
   // Look for std::__debug for libstdc++, and for std:: for stlport.
   // This is effectively a compiler-side implementation of LWG2193.
-  if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
+  if (!InitSeq && EmptyInitList &&
+      InitSeq.getFailureKind() ==
           InitializationSequence::FK_ExplicitConstructor) {
     OverloadCandidateSet::iterator Best;
     OverloadingResult O =
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 0de569ebc..91d4b1e15 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1458,7 +1458,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
       SemaRef.getSourceManager().isInSystemHeader(D->getBeginLoc()))
     // Fold it to the (non-reference) type which g++ would have produced.
     DI = SemaRef.Context.getTrivialTypeSourceInfo(
-      DI->getType().getNonReferenceType());
+        DI->getType().getNonReferenceType());
 
   // Create the new typedef
   TypedefNameDecl *Typedef;

@cor3ntin cor3ntin merged commit 16c13e5 into main Jun 3, 2025
13 of 14 checks passed
@cor3ntin cor3ntin deleted the revert-141977-corentin/libstd_workaround branch June 3, 2025 10:27
rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants