https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/103015
None >From 0d5bad32df4b65a38604bb51b64a4b2ca3cc40ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 13 Aug 2024 09:16:58 +0200 Subject: [PATCH] [clang][Interp] Diagnose pointer subtraction on zero-size arrays --- clang/lib/AST/Interp/Interp.h | 16 ++++++++++++++++ clang/lib/AST/Interp/Pointer.h | 6 +++++- clang/test/AST/Interp/arrays.cpp | 13 +++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 67b3fc50645097..3eab0cfd871385 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 07ff8025ba9541..01ccb88ec03b29 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 98cd17276e0a06..47706bedcf3f0c 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}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits