https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/157695
All pointer types can be null, so check that independently from the pointer type. Fixes #157650 >From e9a03f5cdde76fd44e4d90b5fe8fd5f999c7d4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 9 Sep 2025 17:33:13 +0200 Subject: [PATCH] [clang][bytecode] Check reads for null block pointers All pointer types can be null, so check that independently from the pointer type. Fixes #157650 --- clang/lib/AST/ByteCode/Interp.cpp | 18 +++++++++--------- clang/test/AST/ByteCode/references.cpp | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 10 deletions(-) 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}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits