From 19e2174d54356e1654583a65ff9cd38eccf797ee Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Sat, 2 Dec 2023 13:35:27 +0100 Subject: [PATCH] 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 --- clang/docs/ReleaseNotes.rst | 5 ---- clang/include/clang/Sema/ExternalSemaSource.h | 3 -- .../clang/Sema/MultiplexExternalSemaSource.h | 3 -- clang/include/clang/Sema/Sema.h | 10 ------- .../include/clang/Serialization/ASTBitCodes.h | 4 --- clang/include/clang/Serialization/ASTReader.h | 6 ---- .../lib/Sema/MultiplexExternalSemaSource.cpp | 6 ---- clang/lib/Sema/SemaDecl.cpp | 3 -- clang/lib/Sema/SemaExpr.cpp | 9 ++---- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 28 ----------------- clang/lib/Serialization/ASTReader.cpp | 27 ----------------- clang/lib/Serialization/ASTWriter.cpp | 16 ---------- .../instantiate-used-constexpr-function.cpp | 17 ----------- .../instantiate-used-constexpr-function.cpp | 30 ------------------- 14 files changed, 2 insertions(+), 165 deletions(-) delete mode 100644 clang/test/PCH/instantiate-used-constexpr-function.cpp delete mode 100644 clang/test/SemaTemplate/instantiate-used-constexpr-function.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 06796780f3224a..c7a948fd3fae5b 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 `_) -- 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 `_) - 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 8b41c5483458a0..22d1ee2df115a6 100644 --- a/clang/include/clang/Sema/ExternalSemaSource.h +++ b/clang/include/clang/Sema/ExternalSemaSource.h @@ -181,9 +181,6 @@ class ExternalSemaSource : public ExternalASTSource { SmallVectorImpl > &Pending) {} - virtual void ReadPendingInstantiationsOfConstexprEntity( - const NamedDecl *D, llvm::SmallSetVector &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 6054ef39e54ff9..2bf91cb5212c5e 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 >& Pending) override; - virtual void ReadPendingInstantiationsOfConstexprEntity( - const NamedDecl *D, llvm::SmallSetVector &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 8b2ed6f7cd8cd8..e745c01ae0ae0f 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 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> - PendingInstantiationsOfConstexprEntities; - /// Queue of implicit template instantiations that cannot be performed /// eagerly. SmallVector 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 08642889b0cf3e..fdd64f2abbe937 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 407fc614f483e6..7eefdca6815cda 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 PendingInstantiations; - llvm::DenseMap> - PendingInstantiationsOfConstexprEntities; - //@} /// \name DiagnosticsEngine-relevant special data @@ -2104,9 +2101,6 @@ class ASTReader SmallVectorImpl> &Pending) override; - virtual void ReadPendingInstantiationsOfConstexprEntity( - const NamedDecl *D, llvm::SmallSetVector &Decls) override; - void ReadLateParsedTemplates( llvm::MapVector> &LPTMap) override; diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 100794de60ee03..058e22cb2b814e 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 &Decls) { - for (size_t i = 0; i < Sources.size(); ++i) - Sources[i]->ReadPendingInstantiationsOfConstexprEntity(D, Decls); -} - void MultiplexExternalSemaSource::ReadLateParsedTemplates( llvm::MapVector> &LPTMap) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c0d21ec330acfd..f12424d33b7da2 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 b204cb01a0deff..d1b2b8084b8ffe 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 aa367e0083e6db..d768bb72e07c09 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(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 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 ef191c23650752..f22da838424b41 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 &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(GetDecl(InstantiationId))); - } -} - void ASTReader::ReadLateParsedTemplates( llvm::MapVector> &LPTMap) { diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 8c8048fce026ef..6df815234e235f 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 3930d0467d866b..00000000000000 --- 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 constexpr T f(); -constexpr int g() { return f(); } // #1 - -#else /*included pch*/ - -template 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 61a7fb01376805..00000000000000 --- 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 -struct basic_string { - constexpr void _M_construct(); - constexpr basic_string() { - _M_construct(); - } -}; - -basic_string a; - -template -constexpr void basic_string<_CharT>::_M_construct(){} -constexpr basic_string str{}; - -template -constexpr void g(T); - -constexpr int f() { g(0); return 0; } - -template -constexpr void g(T) {} - -constexpr int z = f(); - -}