diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 77ff901634a462..a13cd94b0ba1c9 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -56,6 +56,7 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E, EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, bool CheckFullyInitialized) { this->CheckFullyInitialized = CheckFullyInitialized; + S.EvaluatingDecl = VD; if (const Expr *Init = VD->getAnyInitializer()) { QualType T = VD->getType(); @@ -69,6 +70,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, if (!this->visitDecl(VD, S.inConstantContext()) && EvalResult.empty()) EvalResult.setInvalid(); + S.EvaluatingDecl = nullptr; return std::move(this->EvalResult); } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index fc4c0058fbda44..76a0751a006e4c 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -322,7 +322,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { }; if (const auto *D = Desc->asVarDecl(); - D && D->hasGlobalStorage() && !IsConstType(D)) { + D && D->hasGlobalStorage() && D != S.EvaluatingDecl && !IsConstType(D)) { diagnoseNonConstVariable(S, OpPC, D); return S.inConstantContext(); } diff --git a/clang/lib/AST/Interp/InterpState.h b/clang/lib/AST/Interp/InterpState.h index 0938a723a76d09..925395b6eba0ce 100644 --- a/clang/lib/AST/Interp/InterpState.h +++ b/clang/lib/AST/Interp/InterpState.h @@ -121,6 +121,8 @@ class InterpState final : public State, public SourceMapper { InterpFrame *Current = nullptr; /// Source location of the evaluating expression SourceLocation EvalLocation; + /// Declaration we're initializing/evaluting, if any. + const VarDecl *EvaluatingDecl = nullptr; }; } // namespace interp