llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> Fixes #<!-- -->154312 --- Full diff: https://github.com/llvm/llvm-project/pull/154484.diff 6 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.cpp (+2-2) - (modified) clang/lib/AST/ByteCode/Interp.h (+4-2) - (modified) clang/lib/AST/ByteCode/Pointer.cpp (+1-1) - (modified) clang/lib/AST/ByteCode/Pointer.h (+1-1) - (modified) clang/test/AST/ByteCode/arrays.cpp (+4) - (modified) clang/unittests/AST/ByteCode/Descriptor.cpp (+5-1) ``````````diff diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index aeab9ff381711..631f814adf3c1 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -530,7 +530,7 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK) { - if (!Ptr.isElementPastEnd()) + if (!Ptr.isElementPastEnd() && !Ptr.isZeroSizeArray()) return true; const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) @@ -1312,7 +1312,7 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, return false; } - if (!Ptr.isRoot() || Ptr.isOnePastEnd() || + if (!Ptr.isRoot() || (Ptr.isOnePastEnd() && !Ptr.isZeroSizeArray()) || (Ptr.isArrayElement() && Ptr.getIndex() != 0)) { const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_delete_subobject) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 75901e59d8505..149ce3b1042db 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3158,8 +3158,10 @@ inline bool ArrayDecay(InterpState &S, CodePtr OpPC) { return true; } - if (!CheckRange(S, OpPC, Ptr, CSK_ArrayToPointer)) - return false; + if (!Ptr.isZeroSizeArray()) { + if (!CheckRange(S, OpPC, Ptr, CSK_ArrayToPointer)) + return false; + } if (Ptr.isRoot() || !Ptr.isUnknownSizeArray()) { S.Stk.push<Pointer>(Ptr.atIndex(0)); diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 7c6eb74da205c..0dd22ba0828e3 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -209,7 +209,7 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { UsePath = false; // Build the path into the object. - bool OnePastEnd = isOnePastEnd(); + bool OnePastEnd = isOnePastEnd() && !isZeroSizeArray(); Pointer Ptr = *this; while (Ptr.isField() || Ptr.isArrayElement()) { diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 27659d7eeaf09..507d99e7438b4 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -657,7 +657,7 @@ class Pointer { if (isUnknownSizeArray()) return false; - return isPastEnd() || (getSize() == getOffset() && !isZeroSizeArray()); + return isPastEnd() || (getSize() == getOffset()); } /// Checks if the pointer points past the end of the object. diff --git a/clang/test/AST/ByteCode/arrays.cpp b/clang/test/AST/ByteCode/arrays.cpp index 8ef5e4d8346d4..68102b42f3820 100644 --- a/clang/test/AST/ByteCode/arrays.cpp +++ b/clang/test/AST/ByteCode/arrays.cpp @@ -795,4 +795,8 @@ namespace ZeroSizeArrayRead { constexpr const char *p1 = &str[0]; constexpr const char *p2 = &str[1]; // both-error {{must be initialized by a constant expression}} \ // both-note {{cannot refer to element 1 of array of 0 elements in a constant expression}} + + constexpr char s[] = {}; + static_assert(s[0] == '0', ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of dereferenced one-past-the-end pointer}} } diff --git a/clang/unittests/AST/ByteCode/Descriptor.cpp b/clang/unittests/AST/ByteCode/Descriptor.cpp index b3517d8731c85..22930ca162d0c 100644 --- a/clang/unittests/AST/ByteCode/Descriptor.cpp +++ b/clang/unittests/AST/ByteCode/Descriptor.cpp @@ -399,7 +399,11 @@ TEST(Descriptor, Primitives) { const Pointer &PF5 = GlobalPtr.atField(F5->Offset); ASSERT_TRUE(PF5.isZeroSizeArray()); - ASSERT_FALSE(PF5.isOnePastEnd()); + ASSERT_TRUE(PF5.isOnePastEnd()); ASSERT_FALSE(PF5.isElementPastEnd()); + + const Pointer &E1 = PF5.atIndex(0); + ASSERT_FALSE(PF5.isOnePastEnd()); + ASSERT_TRUE(PF5.isElementPastEnd()); } } `````````` </details> https://github.com/llvm/llvm-project/pull/154484 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits