diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index b64ed8c2fb497..b961a413fbe78 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -792,18 +792,18 @@ bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) { bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { - // Block pointers are the only ones we can actually read from. - if (!Ptr.isBlockPointer()) { - if (Ptr.isZero()) { - const auto &Src = S.Current->getSource(OpPC); + if (Ptr.isZero()) { + const auto &Src = S.Current->getSource(OpPC); - if (Ptr.isField()) - S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field; - else - S.FFDiag(Src, diag::note_constexpr_access_null) << AK; - } + if (Ptr.isField()) + S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field; + else + S.FFDiag(Src, diag::note_constexpr_access_null) << AK; return false; } + // Block pointers are the only ones we can actually read from. + if (!Ptr.isBlockPointer()) + return false; if (!Ptr.block()->isAccessible()) { if (!CheckLive(S, OpPC, Ptr, AK)) diff --git a/clang/test/AST/ByteCode/references.cpp b/clang/test/AST/ByteCode/references.cpp index 36609b7df3f59..3da3996aaca75 100644 --- a/clang/test/AST/ByteCode/references.cpp +++ b/clang/test/AST/ByteCode/references.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s -// RUN: %clang_cc1 -verify=ref,both %s +// RUN: %clang_cc1 -verify=ref,both %s constexpr int a = 10; @@ -178,3 +178,19 @@ namespace Params { static_assert(foo()); } + +namespace ReadFromNullBlockPtr { + struct S { + int *const &t; + }; + + void foo(int x) { + constexpr S s = {&x}; // both-error {{must be initialized by a constant expression}} \ + // both-note {{reference to temporary}} \ + // both-note {{created here}} \ + // ref-note {{declared here}} + static_assert(s.t == &x, ""); // both-error {{not an integral constant expression}} \ + // expected-note {{read of dereferenced null pointer}} \ + // ref-note {{initializer of 's' is not a constant expression}} + } +}