Skip to content

Commit 840c7c6

Browse files
committed
[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.
1 parent 1752b7b commit 840c7c6

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

clang/lib/AST/Interp/Pointer.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,17 @@ class Pointer {
211211

212212
/// Expands a pointer to the containing array, undoing narrowing.
213213
[[nodiscard]] Pointer expand() const {
214+
assert(isBlockPointer());
215+
Block *Pointee = asBlockPointer().Pointee;
216+
214217
if (isElementPastEnd()) {
215218
// Revert to an outer one-past-end pointer.
216219
unsigned Adjust;
217220
if (inPrimitiveArray())
218221
Adjust = sizeof(InitMapPtr);
219222
else
220223
Adjust = sizeof(InlineDescriptor);
221-
return Pointer(asBlockPointer().Pointee, asBlockPointer().Base,
224+
return Pointer(Pointee, asBlockPointer().Base,
222225
asBlockPointer().Base + getSize() + Adjust);
223226
}
224227

@@ -228,15 +231,17 @@ class Pointer {
228231

229232
// If at base, point to an array of base types.
230233
if (isRoot())
231-
return Pointer(asBlockPointer().Pointee, RootPtrMark, 0);
234+
return Pointer(Pointee, RootPtrMark, 0);
232235

233236
// Step into the containing array, if inside one.
234237
unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset;
235238
const Descriptor *Desc =
236-
Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc;
239+
(Next == Pointee->getDescriptor()->getMetadataSize())
240+
? getDeclDesc()
241+
: getDescriptor(Next)->Desc;
237242
if (!Desc->IsArray)
238243
return *this;
239-
return Pointer(asBlockPointer().Pointee, Next, Offset);
244+
return Pointer(Pointee, Next, Offset);
240245
}
241246

242247
/// Checks if the pointer is null.

clang/test/AST/Interp/arrays.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,3 +625,10 @@ constexpr int *get2() {
625625
return same_entity_2;
626626
}
627627
static_assert(get2() == same_entity_2, "failed to find previous decl");
628+
629+
constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
630+
constexpr int fail(const int &p) {
631+
return (&p)[64]; // both-note {{cannot refer to element 64 of array of 2 elements}}
632+
}
633+
static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // both-error {{not an integral constant expression}} \
634+
// both-note {{in call to}}

0 commit comments

Comments
 (0)