llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> createGlobal fails e.g. if the type isn't complete. --- Full diff: https://github.com/llvm/llvm-project/pull/102464.diff 3 Files Affected: - (modified) clang/lib/AST/Interp/Compiler.cpp (+11-7) - (modified) clang/lib/AST/Interp/Compiler.h (+6-5) - (modified) clang/test/AST/Interp/records.cpp (+10) ``````````diff diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index 11fe2acf2d7b9..165fabbfe3d73 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -3617,7 +3617,7 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD) { auto R = this->visitVarDecl(VD, /*Toplevel=*/true); - if (R.notCreated()) + if (R.notCreated() || R.dummyCreated()) return R; if (R) @@ -3709,7 +3709,7 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve // This case is EvalEmitter-only. If we won't create any instructions for the // initializer anyway, don't bother creating the variable in the first place. if (!this->isActive()) - return VarCreationState::NotCreated(); + return VarCreationState::NotCreated; const Expr *Init = VD->getInit(); std::optional<PrimType> VarT = classify(VD->getType()); @@ -3759,12 +3759,16 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve return Init && checkDecl() && initGlobal(*GlobalIndex); } - std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init); + if (std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init)) + return !Init || (checkDecl() && initGlobal(*GlobalIndex)); - if (!GlobalIndex) - return false; + if (std::optional<unsigned> I = P.getOrCreateDummy(VD)) { + if (!this->emitGetPtrGlobal(*I, VD)) + return false; + return VarCreationState::DummyCreated; + } - return !Init || (checkDecl() && initGlobal(*GlobalIndex)); + return false; } else { InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD)); @@ -5240,7 +5244,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) { auto revisit = [&](const VarDecl *VD) -> bool { auto VarState = this->visitDecl(VD); - if (VarState.notCreated()) + if (VarState.notCreated() || VarState.dummyCreated()) return true; if (!VarState) return false; diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h index 244a600d061f4..4888e499bd6d4 100644 --- a/clang/lib/AST/Interp/Compiler.h +++ b/clang/lib/AST/Interp/Compiler.h @@ -89,13 +89,14 @@ struct InitLink { /// State encapsulating if a the variable creation has been successful, /// unsuccessful, or no variable has been created at all. struct VarCreationState { - std::optional<bool> S = std::nullopt; + enum SS { Failure = 0, Success = 1, NotCreated, DummyCreated } S; VarCreationState() = default; - VarCreationState(bool b) : S(b) {} - static VarCreationState NotCreated() { return VarCreationState(); } + VarCreationState(SS b) : S(b) {} + VarCreationState(bool b) : S(b ? Success : Failure) {} - operator bool() const { return S && *S; } - bool notCreated() const { return !S; } + operator bool() const { return S == Success; } + bool notCreated() const { return S == NotCreated; } + bool dummyCreated() const { return S == DummyCreated; } }; /// Compilation context for expressions. diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 479c0487fecae..48c07e2953ebf 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1576,3 +1576,13 @@ namespace ctorOverrider { constexpr Covariant1 cb; } #endif + +namespace IncompleteStaticStructMember { + struct Foo; + struct Bar { + static const Foo x; + static const Foo y; + }; + static_assert(&Bar::x != nullptr, ""); // both-warning {{always true}} + static_assert(&Bar::x != &Bar::y, ""); +} `````````` </details> https://github.com/llvm/llvm-project/pull/102464 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits