diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 59e78686b78adf..221bbfdc542ff2 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -169,7 +169,9 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; // Never allow reading from a non-const pointer, unless the memory // has been created in this evaluation. - if (!Ptr.isConst() && Ptr.block()->getEvalID() != Ctx.getEvalID()) + if (!Ptr.isZero() && Ptr.isBlockPointer() && + Ptr.block()->getEvalID() != Ctx.getEvalID() && + (!CheckLoad(S, OpPC, Ptr, AK_Read) || !Ptr.isConst())) return false; if (std::optional V = diff --git a/clang/test/AST/Interp/cxx11.cpp b/clang/test/AST/Interp/cxx11.cpp index 92ab9b605f30d8..cf2dfba079ef7e 100644 --- a/clang/test/AST/Interp/cxx11.cpp +++ b/clang/test/AST/Interp/cxx11.cpp @@ -152,3 +152,11 @@ void A::f(SortOrder order) { return; } } + +namespace FinalLtorDiags { + template struct A {}; // both-note {{template parameter is declared here}} + int k; + int *q = &k; // both-note {{declared here}} + A c; // both-error {{non-type template argument of type 'int *' is not a constant expression}} \ + // both-note {{read of non-constexpr variable 'q' is not allowed in a constant expression}} +}