Author: Timm Bäder Date: 2024-07-12T17:18:26+02:00 New Revision: 840c7c6e1fba52748e3ceccd2842e5d96f658f2e
URL: https://github.com/llvm/llvm-project/commit/840c7c6e1fba52748e3ceccd2842e5d96f658f2e DIFF: https://github.com/llvm/llvm-project/commit/840c7c6e1fba52748e3ceccd2842e5d96f658f2e.diff LOG: [clang][Interp] Fix Pointer::expand() checking for metadata size The == 0 check here was used before blocks had metadata, but doesn't work anymore today. Added: Modified: clang/lib/AST/Interp/Pointer.h clang/test/AST/Interp/arrays.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 7785da1d68f63..0ebac1ba04551 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -211,6 +211,9 @@ class Pointer { /// Expands a pointer to the containing array, undoing narrowing. [[nodiscard]] Pointer expand() const { + assert(isBlockPointer()); + Block *Pointee = asBlockPointer().Pointee; + if (isElementPastEnd()) { // Revert to an outer one-past-end pointer. unsigned Adjust; @@ -218,7 +221,7 @@ class Pointer { Adjust = sizeof(InitMapPtr); else Adjust = sizeof(InlineDescriptor); - return Pointer(asBlockPointer().Pointee, asBlockPointer().Base, + return Pointer(Pointee, asBlockPointer().Base, asBlockPointer().Base + getSize() + Adjust); } @@ -228,15 +231,17 @@ class Pointer { // If at base, point to an array of base types. if (isRoot()) - return Pointer(asBlockPointer().Pointee, RootPtrMark, 0); + return Pointer(Pointee, RootPtrMark, 0); // Step into the containing array, if inside one. unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset; const Descriptor *Desc = - Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc; + (Next == Pointee->getDescriptor()->getMetadataSize()) + ? getDeclDesc() + : getDescriptor(Next)->Desc; if (!Desc->IsArray) return *this; - return Pointer(asBlockPointer().Pointee, Next, Offset); + return Pointer(Pointee, Next, Offset); } /// Checks if the pointer is null. diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index 933437c3401c4..612bd552aed48 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -625,3 +625,10 @@ constexpr int *get2() { return same_entity_2; } static_assert(get2() == same_entity_2, "failed to find previous decl"); + +constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +constexpr int fail(const int &p) { + return (&p)[64]; // both-note {{cannot refer to element 64 of array of 2 elements}} +} +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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits