https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/113132
None >From 8a60b9fc2990708eb8ac34d2f7d53ed8f6fcda6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 21 Oct 2024 08:59:44 +0200 Subject: [PATCH] [clang][bytecode] Allow ArrayElemPtr ops on null pointers --- clang/lib/AST/ByteCode/Interp.h | 12 +++++++----- clang/test/AST/ByteCode/complex.cpp | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index aafc848a9c53f3..1469fac5a17776 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) { template <class T, ArithOp Op> bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, - const Pointer &Ptr) { + const Pointer &Ptr, bool IsPointerArith = false) { // A zero offset does not change the pointer. if (Offset.isZero()) { S.Stk.push<Pointer>(Ptr); return true; } - if (!CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) { + if (IsPointerArith && !CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) { // The CheckNull will have emitted a note already, but we only // abort in C++, since this is fine in C. if (S.getLangOpts().CPlusPlus) @@ -2063,14 +2063,16 @@ bool AddOffset(InterpState &S, CodePtr OpPC) { Pointer Ptr = S.Stk.pop<Pointer>(); if (Ptr.isBlockPointer()) Ptr = Ptr.expand(); - return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr); + return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr, + /*IsPointerArith=*/true); } template <PrimType Name, class T = typename PrimConv<Name>::T> bool SubOffset(InterpState &S, CodePtr OpPC) { const T &Offset = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.pop<Pointer>(); - return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr); + return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr, + /*IsPointerArith=*/true); } template <ArithOp Op> @@ -2090,7 +2092,7 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC, // Now the current Ptr again and a constant 1. OneT One = OneT::from(1); - if (!OffsetHelper<OneT, Op>(S, OpPC, One, P)) + if (!OffsetHelper<OneT, Op>(S, OpPC, One, P, /*IsPointerArith=*/true)) return false; // Store the new value. diff --git a/clang/test/AST/ByteCode/complex.cpp b/clang/test/AST/ByteCode/complex.cpp index dc93c786dac7ae..ee11c6214b70c5 100644 --- a/clang/test/AST/ByteCode/complex.cpp +++ b/clang/test/AST/ByteCode/complex.cpp @@ -407,8 +407,7 @@ namespace ComplexConstexpr { // ref-note {{cannot access real component of null}} \ // expected-note {{read of dereferenced null pointer}} constexpr float pi = __imag *p; // both-error {{constant expr}} \ - // ref-note {{cannot access imaginary component of null}} \ - // expected-note {{cannot perform pointer arithmetic on null pointer}} + // ref-note {{cannot access imaginary component of null}} constexpr const _Complex double *q = &test3 + 1; constexpr double qr = __real *q; // ref-error {{constant expr}} \ // ref-note {{cannot access real component of pointer past the end}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits