[clang] [clang][bytecode] Allow ArrayElemPtr ops on null pointers (PR #113132)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 21 00:22:32 PDT 2024
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?= <tbaeder at 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}}
More information about the cfe-commits
mailing list