Skip to content

Commit fb1c2db

Browse files
committed
Revert "Reapply "[clang][Interp] Create full type info for dummy pointers""
This reverts commit 1aeb64c. Due to failures in 32 bit Arm builds: https://lab.llvm.org/buildbot/#/builders/245/builds/24041
1 parent 4e67b50 commit fb1c2db

File tree

6 files changed

+56
-33
lines changed

6 files changed

+56
-33
lines changed

clang/lib/AST/Interp/Descriptor.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,14 @@ Descriptor::Descriptor(const DeclTy &D)
347347
assert(Source && "Missing source");
348348
}
349349

350+
/// Dummy array.
351+
Descriptor::Descriptor(const DeclTy &D, UnknownSize)
352+
: Source(D), ElemSize(1), Size(UnknownSizeMark), MDSize(0),
353+
AllocSize(MDSize), ElemRecord(nullptr), IsConst(true), IsMutable(false),
354+
IsTemporary(false), IsArray(true), IsDummy(true) {
355+
assert(Source && "Missing source");
356+
}
357+
350358
QualType Descriptor::getType() const {
351359
if (auto *E = asExpr())
352360
return E->getType();

clang/lib/AST/Interp/Descriptor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ struct Descriptor final {
128128
/// Flag indicating if the block is an array.
129129
const bool IsArray = false;
130130
/// Flag indicating if this is a dummy descriptor.
131-
bool IsDummy = false;
131+
const bool IsDummy = false;
132132

133133
/// Storage management methods.
134134
const BlockCtorFn CtorFn = nullptr;
@@ -162,8 +162,8 @@ struct Descriptor final {
162162
/// Allocates a dummy descriptor.
163163
Descriptor(const DeclTy &D);
164164

165-
/// Make this descriptor a dummy descriptor.
166-
void makeDummy() { IsDummy = true; }
165+
/// Allocates a dummy array descriptor.
166+
Descriptor(const DeclTy &D, UnknownSize);
167167

168168
QualType getType() const;
169169
QualType getElemQualType() const;

clang/lib/AST/Interp/Interp.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -823,9 +823,9 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
823823
// element in the same array are NOT equal. They have the same Base value,
824824
// but a different Offset. This is a pretty rare case, so we fix this here
825825
// by comparing pointers to the first elements.
826-
if (!LHS.isZero() && LHS.isArrayRoot())
826+
if (!LHS.isZero() && !LHS.isDummy() && LHS.isArrayRoot())
827827
VL = LHS.atIndex(0).getByteOffset();
828-
if (!RHS.isZero() && RHS.isArrayRoot())
828+
if (!RHS.isZero() && !RHS.isDummy() && RHS.isArrayRoot())
829829
VR = RHS.atIndex(0).getByteOffset();
830830

831831
S.Stk.push<BoolT>(BoolT::from(Fn(Compare(VL, VR))));
@@ -1241,16 +1241,14 @@ inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
12411241
!CheckNull(S, OpPC, Ptr, CSK_Field))
12421242
return false;
12431243

1244-
if (!CheckExtern(S, OpPC, Ptr))
1245-
return false;
1246-
if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1247-
return false;
1248-
if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1249-
return false;
1250-
1251-
if (Ptr.isBlockPointer() && Off > Ptr.block()->getSize())
1252-
return false;
1253-
1244+
if (CheckDummy(S, OpPC, Ptr)) {
1245+
if (!CheckExtern(S, OpPC, Ptr))
1246+
return false;
1247+
if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1248+
return false;
1249+
if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1250+
return false;
1251+
}
12541252
S.Stk.push<Pointer>(Ptr.atField(Off));
12551253
return true;
12561254
}
@@ -2036,6 +2034,11 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
20362034
if (!Ptr.isZero()) {
20372035
if (!CheckArray(S, OpPC, Ptr))
20382036
return false;
2037+
2038+
if (Ptr.isDummy()) {
2039+
S.Stk.push<Pointer>(Ptr);
2040+
return true;
2041+
}
20392042
}
20402043

20412044
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
@@ -2052,6 +2055,11 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
20522055
if (!Ptr.isZero()) {
20532056
if (!CheckArray(S, OpPC, Ptr))
20542057
return false;
2058+
2059+
if (Ptr.isDummy()) {
2060+
S.Stk.push<Pointer>(Ptr);
2061+
return true;
2062+
}
20552063
}
20562064

20572065
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
@@ -2105,12 +2113,12 @@ inline bool CopyArray(InterpState &S, CodePtr OpPC, uint32_t SrcIndex, uint32_t
21052113
inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
21062114
const Pointer &Ptr = S.Stk.pop<Pointer>();
21072115

2108-
if (Ptr.isZero()) {
2116+
if (Ptr.isZero() || Ptr.isDummy()) {
21092117
S.Stk.push<Pointer>(Ptr);
21102118
return true;
21112119
}
21122120

2113-
if (!Ptr.isUnknownSizeArray() || Ptr.isDummy()) {
2121+
if (!Ptr.isUnknownSizeArray()) {
21142122
S.Stk.push<Pointer>(Ptr.atIndex(0));
21152123
return true;
21162124
}

clang/lib/AST/Interp/Program.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,17 @@ std::optional<unsigned> Program::getOrCreateDummy(const ValueDecl *VD) {
144144
if (auto It = DummyVariables.find(VD); It != DummyVariables.end())
145145
return It->second;
146146

147+
// Create dummy descriptor.
148+
// We create desriptors of 'array of unknown size' if the type is an array
149+
// type _and_ the size isn't known (it's not a ConstantArrayType). If the size
150+
// is known however, we create a regular dummy pointer.
147151
Descriptor *Desc;
148-
if (std::optional<PrimType> T = Ctx.classify(VD->getType()))
149-
Desc = createDescriptor(VD, *T, std::nullopt, true, false);
152+
if (const auto *AT = VD->getType()->getAsArrayTypeUnsafe();
153+
AT && !isa<ConstantArrayType>(AT))
154+
Desc = allocateDescriptor(VD, Descriptor::UnknownSize{});
150155
else
151-
Desc = createDescriptor(VD, VD->getType().getTypePtr(), std::nullopt, true,
152-
false);
153-
if (!Desc)
154156
Desc = allocateDescriptor(VD);
155157

156-
assert(Desc);
157-
Desc->makeDummy();
158-
159-
assert(Desc->isDummy());
160-
161158
// Allocate a block for storage.
162159
unsigned I = Globals.size();
163160

@@ -313,7 +310,8 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
313310
for (const FieldDecl *FD : RD->fields()) {
314311
// Note that we DO create fields and descriptors
315312
// for unnamed bitfields here, even though we later ignore
316-
// them everywhere. That's so the FieldDecl's getFieldIndex() matches.
313+
// them everywhere. That's because so the FieldDecl's
314+
// getFieldIndex() matches.
317315

318316
// Reserve space for the field's descriptor and the offset.
319317
BaseSize += align(sizeof(InlineDescriptor));
@@ -346,7 +344,6 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
346344
Descriptor::MetadataSize MDSize,
347345
bool IsConst, bool IsTemporary,
348346
bool IsMutable, const Expr *Init) {
349-
350347
// Classes and structures.
351348
if (const auto *RT = Ty->getAs<RecordType>()) {
352349
if (const auto *Record = getOrCreateRecord(RT->getDecl()))

clang/test/AST/Interp/builtin-align-cxx.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -std=c++11 %s -fsyntax-only -verify=expected,both -fexperimental-new-constant-interpreter
33
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -std=c++11 %s -fsyntax-only -verify=ref,both
44

5+
6+
/// This is just a copy of the one from test/SemaCXX/ with some of the
7+
/// diagnostic output adapted.
8+
/// Also, align32array has an initializer now, which means it's not just
9+
/// a dummy pointer for us and we do actually have type information for it.
10+
/// In the future, we need to retain type information for dummy pointers as
11+
/// well, so here is a test that will break once we do that:
12+
namespace {
13+
_Alignas(32) char heh[4];
14+
static_assert(!__builtin_is_aligned(&heh[1], 4), ""); // expected-error {{failed}}
15+
}
16+
17+
518
// Check that we don't crash when using dependent types in __builtin_align:
619
template <typename a, a b>
720
void *c(void *d) { // both-note{{candidate template ignored}}
@@ -164,7 +177,7 @@ static_assert(wrap_align_up(static_cast<bool>(1), const_value(1 << 21)), ""); //
164177
// both-note@-1{{in instantiation of function template specialization 'wrap_align_up<bool>' requested here}}
165178

166179
// Check constant evaluation for pointers:
167-
_Alignas(32) char align32array[128];
180+
_Alignas(32) char align32array[128] = {};
168181
static_assert(&align32array[0] == &align32array[0], "");
169182
// __builtin_align_up/down can be constant evaluated as a no-op for values
170183
// that are known to have greater alignment:

clang/test/AST/Interp/c.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,3 @@ int test3(void) {
270270
a[0] = test3; // all-error {{incompatible pointer to integer conversion assigning to 'int' from 'int (void)'}}
271271
return 0;
272272
}
273-
/// This tests that we have full type info, even for values we cannot read.
274-
int dummyarray[5];
275-
_Static_assert(&dummyarray[0] < &dummyarray[1], ""); // pedantic-warning {{GNU extension}}

0 commit comments

Comments
 (0)