[clang] 19e2174 - Revert "[Clang] Eagerly instantiate used constexpr function upon definition. (#73463)"

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 2 04:36:29 PST 2023


Author: Corentin Jabot
Date: 2023-12-02T13:35:27+01:00
New Revision: 19e2174d54356e1654583a65ff9cd38eccf797ee

URL: https://github.com/llvm/llvm-project/commit/19e2174d54356e1654583a65ff9cd38eccf797ee
DIFF: https://github.com/llvm/llvm-project/commit/19e2174d54356e1654583a65ff9cd38eccf797ee.diff

LOG: Revert "[Clang] Eagerly instantiate used constexpr function upon definition. (#73463)"

This reverts commit 030047c432cac133738be68fa0974f70e69dd58d.

Breaks Qt and is inconsistent with GCC.

See the following issue for details:

Fixes #74069

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Sema/ExternalSemaSource.h
    clang/include/clang/Sema/MultiplexExternalSemaSource.h
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Serialization/ASTBitCodes.h
    clang/include/clang/Serialization/ASTReader.h
    clang/lib/Sema/MultiplexExternalSemaSource.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTWriter.cpp

Removed: 
    clang/test/PCH/instantiate-used-constexpr-function.cpp
    clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 06796780f322..c7a948fd3fae 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -802,11 +802,6 @@ Bug Fixes to C++ Support
 - Fix crash when parsing nested requirement. Fixes:
   (`#73112 <https://github.com/llvm/llvm-project/issues/73112>`_)
 
-- Clang now immediately instantiates function template specializations
-  at the end of the definition of the corresponding function template
-  when the definition appears after the first point of instantiation.
-  (`#73232 <https://github.com/llvm/llvm-project/issues/73232>`_)
-
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.

diff  --git a/clang/include/clang/Sema/ExternalSemaSource.h b/clang/include/clang/Sema/ExternalSemaSource.h
index 8b41c5483458..22d1ee2df115 100644
--- a/clang/include/clang/Sema/ExternalSemaSource.h
+++ b/clang/include/clang/Sema/ExternalSemaSource.h
@@ -181,9 +181,6 @@ class ExternalSemaSource : public ExternalASTSource {
                  SmallVectorImpl<std::pair<ValueDecl *,
                                            SourceLocation> > &Pending) {}
 
-  virtual void ReadPendingInstantiationsOfConstexprEntity(
-      const NamedDecl *D, llvm::SmallSetVector<NamedDecl *, 4> &Decls){};
-
   /// Read the set of late parsed template functions for this source.
   ///
   /// The external source should insert its own late parsed template functions

diff  --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
index 6054ef39e54f..2bf91cb5212c 100644
--- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -319,9 +319,6 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
   void ReadPendingInstantiations(
      SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
 
-  virtual void ReadPendingInstantiationsOfConstexprEntity(
-      const NamedDecl *D, llvm::SmallSetVector<NamedDecl *, 4> &Decls) override;
-
   /// Read the set of late parsed template functions for this source.
   ///
   /// The external source should insert its own late parsed template functions

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 8b2ed6f7cd8c..e745c01ae0ae 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -59,7 +59,6 @@
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -10093,12 +10092,6 @@ class Sema final {
   /// but have not yet been performed.
   std::deque<PendingImplicitInstantiation> PendingInstantiations;
 
-  /// Track constexpr functions referenced before they are (lexically) defined.
-  /// The key is the pattern, associated with a list of specialisations that
-  /// need to be instantiated when the pattern is defined.
-  llvm::DenseMap<NamedDecl *, SmallVector<NamedDecl *>>
-      PendingInstantiationsOfConstexprEntities;
-
   /// Queue of implicit template instantiations that cannot be performed
   /// eagerly.
   SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations;
@@ -10417,9 +10410,6 @@ class Sema final {
                                      bool Recursive = false,
                                      bool DefinitionRequired = false,
                                      bool AtEndOfTU = false);
-
-  void PerformPendingInstantiationsOfConstexprFunctions(FunctionDecl *Template);
-
   VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
       VarTemplateDecl *VarTemplate, VarDecl *FromVar,
       const TemplateArgumentList &TemplateArgList,

diff  --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 08642889b0cf..fdd64f2abbe9 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -695,10 +695,6 @@ enum ASTRecordTypes {
   /// Record code for an unterminated \#pragma clang assume_nonnull begin
   /// recorded in a preamble.
   PP_ASSUME_NONNULL_LOC = 67,
-
-  /// Record code for constexpr templated entities that have been used but not
-  /// yet instantiated.
-  PENDING_INSTANTIATIONS_OF_CONSTEXPR_ENTITIES = 68,
 };
 
 /// Record types used within a source manager block.

diff  --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 407fc614f483..7eefdca6815c 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -814,9 +814,6 @@ class ASTReader
   /// is the instantiation location.
   SmallVector<serialization::DeclID, 64> PendingInstantiations;
 
-  llvm::DenseMap<serialization::DeclID, std::set<serialization::DeclID>>
-      PendingInstantiationsOfConstexprEntities;
-
   //@}
 
   /// \name DiagnosticsEngine-relevant special data
@@ -2104,9 +2101,6 @@ class ASTReader
                   SmallVectorImpl<std::pair<ValueDecl *,
                                             SourceLocation>> &Pending) override;
 
-  virtual void ReadPendingInstantiationsOfConstexprEntity(
-      const NamedDecl *D, llvm::SmallSetVector<NamedDecl *, 4> &Decls) override;
-
   void ReadLateParsedTemplates(
       llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
           &LPTMap) override;

diff  --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
index 100794de60ee..058e22cb2b81 100644
--- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -310,12 +310,6 @@ void MultiplexExternalSemaSource::ReadPendingInstantiations(
     Sources[i]->ReadPendingInstantiations(Pending);
 }
 
-void MultiplexExternalSemaSource::ReadPendingInstantiationsOfConstexprEntity(
-    const NamedDecl *D, llvm::SmallSetVector<NamedDecl *, 4> &Decls) {
-  for (size_t i = 0; i < Sources.size(); ++i)
-    Sources[i]->ReadPendingInstantiationsOfConstexprEntity(D, Decls);
-}
-
 void MultiplexExternalSemaSource::ReadLateParsedTemplates(
     llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
         &LPTMap) {

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c0d21ec330ac..f12424d33b7d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16286,9 +16286,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
   if (FD && !FD->isDeleted())
     checkTypeSupport(FD->getType(), FD->getLocation(), FD);
 
-  if (FD && FD->isConstexpr() && FD->isTemplated())
-    PerformPendingInstantiationsOfConstexprFunctions(FD);
-
   return dcl;
 }
 

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index b204cb01a0de..d1b2b8084b8f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19053,17 +19053,12 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
               CodeSynthesisContexts.size())
             PendingLocalImplicitInstantiations.push_back(
                 std::make_pair(Func, PointOfInstantiation));
-          else if (Func->isConstexpr()) {
+          else if (Func->isConstexpr())
             // Do not defer instantiations of constexpr functions, to avoid the
             // expression evaluator needing to call back into Sema if it sees a
             // call to such a function.
             InstantiateFunctionDefinition(PointOfInstantiation, Func);
-            if (!Func->isDefined()) {
-              PendingInstantiationsOfConstexprEntities
-                  [Func->getTemplateInstantiationPattern()->getCanonicalDecl()]
-                      .push_back(Func);
-            }
-          } else {
+          else {
             Func->setInstantiationIsPending(true);
             PendingInstantiations.push_back(
                 std::make_pair(Func, PointOfInstantiation));

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index aa367e0083e6..d768bb72e07c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6495,34 +6495,6 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) {
     PendingInstantiations.swap(delayedPCHInstantiations);
 }
 
-// Instantiate all referenced specializations of the given function template
-// definition. This make sure that constexpr function templates that are defined
-// after the point of instantiation of their use can be evaluated after they
-// are defined. see CWG2497.
-void Sema::PerformPendingInstantiationsOfConstexprFunctions(FunctionDecl *Tpl) {
-
-  auto InstantiateAll = [&](const auto &Range) {
-    for (NamedDecl *D : Range) {
-      FunctionDecl *Fun = cast<FunctionDecl>(D);
-      InstantiateFunctionDefinition(Fun->getPointOfInstantiation(), Fun);
-    }
-  };
-
-  auto It =
-      PendingInstantiationsOfConstexprEntities.find(Tpl->getCanonicalDecl());
-  if (It != PendingInstantiationsOfConstexprEntities.end()) {
-    auto Decls = std::move(It->second);
-    PendingInstantiationsOfConstexprEntities.erase(It);
-    InstantiateAll(Decls);
-  }
-
-  llvm::SmallSetVector<NamedDecl *, 4> Decls;
-  if (ExternalSource) {
-    ExternalSource->ReadPendingInstantiationsOfConstexprEntity(Tpl, Decls);
-    InstantiateAll(Decls);
-  }
-}
-
 void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
                        const MultiLevelTemplateArgumentList &TemplateArgs) {
   for (auto *DD : Pattern->ddiags()) {

diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ef191c236507..f22da838424b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3709,19 +3709,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       }
       break;
 
-    case PENDING_INSTANTIATIONS_OF_CONSTEXPR_ENTITIES:
-      if (Record.size() % 2 != 0)
-        return llvm::createStringError(
-            std::errc::illegal_byte_sequence,
-            "Invalid PENDING_INSTANTIATIONS_OF_CONSTEXPR_ENTITIES block");
-
-      for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
-        DeclID Key = getGlobalDeclID(F, Record[I++]);
-        DeclID Value = getGlobalDeclID(F, Record[I++]);
-        PendingInstantiationsOfConstexprEntities[Key].insert(Value);
-      }
-      break;
-
     case SEMA_DECL_REFS:
       if (Record.size() != 3)
         return llvm::createStringError(std::errc::illegal_byte_sequence,
@@ -8731,20 +8718,6 @@ void ASTReader::ReadPendingInstantiations(
   PendingInstantiations.clear();
 }
 
-void ASTReader::ReadPendingInstantiationsOfConstexprEntity(
-    const NamedDecl *D, llvm::SmallSetVector<NamedDecl *, 4> &Decls) {
-  for (auto *Redecl : D->redecls()) {
-    if (!Redecl->isFromASTFile())
-      continue;
-    DeclID Id = Redecl->getGlobalID();
-    auto It = PendingInstantiationsOfConstexprEntities.find(Id);
-    if (It == PendingInstantiationsOfConstexprEntities.end())
-      continue;
-    for (DeclID InstantiationId : It->second)
-      Decls.insert(cast<NamedDecl>(GetDecl(InstantiationId)));
-  }
-}
-
 void ASTReader::ReadLateParsedTemplates(
     llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
         &LPTMap) {

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 8c8048fce026..6df815234e23 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -849,7 +849,6 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(SEMA_DECL_REFS);
   RECORD(WEAK_UNDECLARED_IDENTIFIERS);
   RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
-  RECORD(PENDING_INSTANTIATIONS_OF_CONSTEXPR_ENTITIES);
   RECORD(UPDATE_VISIBLE);
   RECORD(DECL_UPDATE_OFFSETS);
   RECORD(DECL_UPDATES);
@@ -4837,16 +4836,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
   assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
          "There are local ones at end of translation unit!");
 
-  // Build a record containing all pending instantiations of constexpr
-  // entities.
-  RecordData PendingInstantiationsOfConstexprEntities;
-  for (const auto &I : SemaRef.PendingInstantiationsOfConstexprEntities) {
-    for (const auto &Elem : I.second) {
-      AddDeclRef(I.first, PendingInstantiationsOfConstexprEntities);
-      AddDeclRef(Elem, PendingInstantiationsOfConstexprEntities);
-    }
-  }
-
   // Build a record containing some declaration references.
   RecordData SemaDeclRefs;
   if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
@@ -5164,11 +5153,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
   if (!PendingInstantiations.empty())
     Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
 
-  // Write the record containing pending instantiations of constexpr entities.
-  if (!PendingInstantiationsOfConstexprEntities.empty())
-    Stream.EmitRecord(PENDING_INSTANTIATIONS_OF_CONSTEXPR_ENTITIES,
-                      PendingInstantiationsOfConstexprEntities);
-
   // Write the record containing declaration references of Sema.
   if (!SemaDeclRefs.empty())
     Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);

diff  --git a/clang/test/PCH/instantiate-used-constexpr-function.cpp b/clang/test/PCH/instantiate-used-constexpr-function.cpp
deleted file mode 100644
index 3930d0467d86..000000000000
--- a/clang/test/PCH/instantiate-used-constexpr-function.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
-
-// expected-no-diagnostics
-
-#ifndef HEADER
-#define HEADER
-
-template<typename T> constexpr T f();
-constexpr int g() { return f<int>(); } // #1
-
-#else /*included pch*/
-
-template<typename T> constexpr T f() { return 123; }
-int k[g()];
-
-#endif // HEADER

diff  --git a/clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp b/clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp
deleted file mode 100644
index 61a7fb013768..000000000000
--- a/clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-namespace GH73232  {
-
-template <typename _CharT>
-struct basic_string {
-  constexpr void _M_construct();
-  constexpr basic_string() {
-    _M_construct();
-  }
-};
-
-basic_string<char> a;
-
-template <typename _CharT>
-constexpr void basic_string<_CharT>::_M_construct(){}
-constexpr basic_string<char> str{};
-
-template <typename T>
-constexpr void g(T);
-
-constexpr int f() { g(0); return 0; }
-
-template <typename T>
-constexpr void g(T) {}
-
-constexpr int z = f();
-
-}


        


More information about the cfe-commits mailing list