[clang] [clang][Interp] Diagnose pointer subtraction on zero-size arrays (PR #103015)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 13 00:19:19 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/103015.diff
3 Files Affected:
- (modified) clang/lib/AST/Interp/Interp.h (+16)
- (modified) clang/lib/AST/Interp/Pointer.h (+5-1)
- (modified) clang/test/AST/Interp/arrays.cpp (+13)
``````````diff
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 67b3fc5064509..3eab0cfd87138 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1987,6 +1987,22 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
const Pointer &LHS = S.Stk.pop<Pointer>();
const Pointer &RHS = S.Stk.pop<Pointer>();
+ for (const Pointer &P : {LHS, RHS}) {
+ if (P.isZeroSizeArray()) {
+ QualType PtrT = P.getType();
+ while (auto *AT = dyn_cast<ArrayType>(PtrT))
+ PtrT = AT->getElementType();
+
+ QualType ArrayTy = S.getCtx().getConstantArrayType(
+ PtrT, APInt::getZero(1), nullptr, ArraySizeModifier::Normal, 0);
+ S.FFDiag(S.Current->getSource(OpPC),
+ diag::note_constexpr_pointer_subtraction_zero_size)
+ << ArrayTy;
+
+ return false;
+ }
+ }
+
if (RHS.isZero()) {
S.Stk.push<T>(T::from(LHS.getIndex()));
return true;
diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 07ff8025ba954..01ccb88ec03b2 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -613,7 +613,11 @@ class Pointer {
bool isElementPastEnd() const { return Offset == PastEndMark; }
/// Checks if the pointer is pointing to a zero-size array.
- bool isZeroSizeArray() const { return getFieldDesc()->isZeroSizeArray(); }
+ bool isZeroSizeArray() const {
+ if (const auto *Desc = getFieldDesc())
+ return Desc->isZeroSizeArray();
+ return false;
+ }
/// Dereferences the pointer, if it's live.
template <typename T> T &deref() const {
diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index 98cd17276e0a0..47706bedcf3f0 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -632,3 +632,16 @@ constexpr int fail(const int &p) {
}
static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}
+
+namespace ZeroSizeTypes {
+ constexpr int (*p1)[0] = 0, (*p2)[0] = 0;
+ constexpr int k = p2 - p1; // both-error {{constexpr variable 'k' must be initialized by a constant expression}} \
+ // both-note {{subtraction of pointers to type 'int[0]' of zero size}} \
+ // both-warning {{subtraction of pointers to type 'int[0]' of zero size has undefined behavior}}
+
+ int arr[5][0];
+ constexpr int f() { // both-error {{never produces a constant expression}}
+ return &arr[3] - &arr[0]; // both-note {{subtraction of pointers to type 'int[0]' of zero size}} \
+ // both-warning {{subtraction of pointers to type 'int[0]' of zero size has undefined behavior}}
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/103015
More information about the cfe-commits
mailing list