diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index c601c02deb0c8..50a712836e3dd 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1339,11 +1339,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { return const_cast(this)->getInitializingDeclaration(); } - /// Checks whether this declaration has an initializer with side effects, - /// without triggering deserialization if the initializer is not yet - /// deserialized. - bool hasInitWithSideEffects() const; - /// Determine whether this variable's value might be usable in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 7b09a4eb9414a..069a38cdc323f 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -51,7 +51,6 @@ class RecordDecl; class Selector; class Stmt; class TagDecl; -class VarDecl; /// Abstract interface for external sources of AST nodes. /// @@ -174,10 +173,6 @@ class ExternalASTSource : public RefCountedBase { virtual ExtKind hasExternalDefinitions(const Decl *D); - virtual bool hasInitializerWithSideEffects(const VarDecl *VD) const { - return false; - } - /// Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// @@ -412,17 +407,6 @@ struct LazyOffsetPtr { return GetPtr(); } - /// Retrieve the pointer to the AST node that this lazy pointer points to, - /// if it can be done without triggering deserialization. - /// - /// \returns a pointer to the AST node, or null if not yet deserialized. - T *getWithoutDeserializing() const { - if (isOffset()) { - return nullptr; - } - return GetPtr(); - } - /// Retrieve the address of the AST node pointer. Deserializes the pointee if /// necessary. T **getAddressOfPointer(ExternalASTSource *Source) const { diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index c7e6c4bc3ffe9..238fb398b7d12 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -92,8 +92,6 @@ class MultiplexExternalSemaSource : public ExternalSemaSource { ExtKind hasExternalDefinitions(const Decl *D) override; - bool hasInitializerWithSideEffects(const VarDecl *VD) const override; - /// Find all declarations with the given name in the /// given context. bool FindExternalVisibleDeclsByName(const DeclContext *DC, diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 90c71fc18fc30..51052290a20e6 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1348,12 +1348,6 @@ class ASTReader const StringRef &operator*() && = delete; }; - /// VarDecls with initializers containing side effects must be emitted, - /// but DeclMustBeEmitted is not allowed to deserialize the intializer. - /// FIXME: Lower memory usage by removing VarDecls once the initializer - /// is deserialized. - llvm::SmallPtrSet InitSideEffectVars; - public: /// Get the buffer for resolving paths. SmallString<0> &getPathBuf() { return PathBuf; } @@ -2269,8 +2263,6 @@ class ASTReader ExtKind hasExternalDefinitions(const Decl *D) override; - bool hasInitializerWithSideEffects(const VarDecl *VD) const override; - /// Retrieve a selector from the given module with its local ID /// number. Selector getLocalSelector(ModuleFile &M, unsigned LocalID); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 973c2c84978c7..8ba7fa2479d04 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13262,7 +13262,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; // Variables that have initialization with side-effects are required. - if (VD->hasInitWithSideEffects()) + if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && + // We can get a value-dependent initializer during error recovery. + (VD->getInit()->isValueDependent() || !VD->evaluateValue())) return true; // Likewise, variables with tuple-like bindings are required if their diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 67a432d2a2cae..cfbb3393183df 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2440,30 +2440,6 @@ VarDecl *VarDecl::getInitializingDeclaration() { return Def; } -bool VarDecl::hasInitWithSideEffects() const { - if (!hasInit()) - return false; - - // Check if we can get the initializer without deserializing - const Expr *E = nullptr; - if (auto *S = dyn_cast(Init)) { - E = cast(S); - } else { - E = cast_or_null(getEvaluatedStmt()->Value.getWithoutDeserializing()); - } - - if (E) - return E->HasSideEffects(getASTContext()) && - // We can get a value-dependent initializer during error recovery. - (E->isValueDependent() || !evaluateValue()); - - assert(getEvaluatedStmt()->Value.isOffset()); - // ASTReader tracks this without having to deserialize the initializer - if (auto Source = getASTContext().getExternalSource()) - return Source->hasInitializerWithSideEffects(this); - return false; -} - bool VarDecl::isOutOfLine() const { if (Decl::isOutOfLine()) return true; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6e5be0eee74f6..d89b9ef6548b9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -16268,12 +16268,6 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes) { assert(!E->isValueDependent()); - // Normally expressions passed to EvaluateInPlace have a type, but not when - // a VarDecl initializer is evaluated before the untyped ParenListExpr is - // replaced with a CXXConstructExpr. This can happen in LLDB. - if (E->getType().isNull()) - return false; - if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E, &This)) return false; diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 56be139814ce1..79e656eb4b7e2 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -107,14 +107,6 @@ MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) { return EK_ReplyHazy; } -bool MultiplexExternalSemaSource::hasInitializerWithSideEffects( - const VarDecl *VD) const { - for (const auto &S : Sources) - if (S->hasInitializerWithSideEffects(VD)) - return true; - return false; -} - bool MultiplexExternalSemaSource:: FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { bool AnyDeclsFound = false; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4da3d09bda3d2..591622f45394e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9268,10 +9268,6 @@ ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) { return I->second ? EK_Never : EK_Always; } -bool ASTReader::hasInitializerWithSideEffects(const VarDecl *VD) const { - return InitSideEffectVars.count(VD); -} - Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) { return DecodeSelector(getGlobalSelectorID(M, LocalID)); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7918cc88648e2..27dbc2f4c9218 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1622,9 +1622,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = VarDeclBits.getNextBit(); - if (VarDeclBits.getNextBit()) - Reader.InitSideEffectVars.insert(VD); - VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit(); HasDeducedType = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.ImplicitParamKind = diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 6885aef8031e7..41391cd0821d6 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1158,7 +1158,6 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VarDeclBits.addBit(D->isConstexpr()); VarDeclBits.addBit(D->isInitCapture()); VarDeclBits.addBit(D->isPreviousDeclInSameBlockScope()); - VarDeclBits.addBit(D->hasInitWithSideEffects()); VarDeclBits.addBit(D->isEscapingByref()); HasDeducedType = D->getType()->getContainedDeducedType(); @@ -1208,11 +1207,10 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { !D->hasExtInfo() && D->getFirstDecl() == D->getMostRecentDecl() && D->getKind() == Decl::Var && !D->isInline() && !D->isConstexpr() && !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() && - !D->hasInitWithSideEffects() && !D->isEscapingByref() && - !HasDeducedType && D->getStorageDuration() != SD_Static && - !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() && - !D->isObjCForDecl() && !isa(D) && - !D->isEscapingByref()) + !D->isEscapingByref() && !HasDeducedType && + D->getStorageDuration() != SD_Static && !D->getDescribedVarTemplate() && + !D->getMemberSpecializationInfo() && !D->isObjCForDecl() && + !isa(D) && !D->isEscapingByref()) AbbrevToUse = Writer.getDeclVarAbbrev(); Code = serialization::DECL_VAR; @@ -2531,12 +2529,12 @@ void ASTWriter::WriteDeclAbbrevs() { // VarDecl Abv->Add(BitCodeAbbrevOp( BitCodeAbbrevOp::Fixed, - 22)); // Packed Var Decl bits: Linkage, ModulesCodegen, + 21)); // Packed Var Decl bits: Linkage, ModulesCodegen, // SClass, TSCSpec, InitStyle, // isARCPseudoStrong, IsThisDeclarationADemotedDefinition, // isExceptionVariable, isNRVOVariable, isCXXForRangeDecl, // isInline, isInlineSpecified, isConstexpr, - // isInitCapture, isPrevDeclInSameScope, hasInitWithSideEffects, + // isInitCapture, isPrevDeclInSameScope, // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl Abv->Add(BitCodeAbbrevOp(0)); // VarKind (local enum) // Type Source Info diff --git a/clang/test/Modules/var-init-side-effects.cpp b/clang/test/Modules/var-init-side-effects.cpp deleted file mode 100644 index 438a9eb204275..0000000000000 --- a/clang/test/Modules/var-init-side-effects.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Tests referencing variable with initializer containing side effect across module boundary -// -// RUN: rm -rf %t -// RUN: mkdir -p %t -// RUN: split-file %s %t - -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Foo.cppm \ -// RUN: -o %t/Foo.pcm - -// RUN: %clang_cc1 -std=c++20 -emit-module-interface \ -// RUN: -fmodule-file=Foo=%t/Foo.pcm \ -// RUN: %t/Bar.cppm \ -// RUN: -o %t/Bar.pcm - -// RUN: %clang_cc1 -std=c++20 -emit-obj \ -// RUN: -main-file-name Bar.cppm \ -// RUN: -fmodule-file=Foo=%t/Foo.pcm \ -// RUN: -x pcm %t/Bar.pcm \ -// RUN: -o %t/Bar.o - -//--- Foo.cppm -export module Foo; - -export { -class S {}; - -inline S s = S{}; -} - -//--- Bar.cppm -export module Bar; -import Foo; - -S bar() { - return s; -} -