Skip to content

Commit 1fe993c

Browse files
authored
[clang][bytecode] Allocate operator new data as array (#146471)
Even if we only allocate one element, we still need to allocate it as a single-element array. This matches what the current interpreter does.
1 parent 8cfd9b8 commit 1fe993c

File tree

2 files changed

+18
-35
lines changed

2 files changed

+18
-35
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,34 +1531,21 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
15311531
std::optional<PrimType> ElemT = S.getContext().classify(ElemType);
15321532
DynamicAllocator &Allocator = S.getAllocator();
15331533
if (ElemT) {
1534-
if (IsArray) {
1535-
Block *B = Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1536-
S.Ctx.getEvalID(),
1537-
DynamicAllocator::Form::Operator);
1538-
assert(B);
1539-
S.Stk.push<Pointer>(Pointer(B).atIndex(0));
1540-
return true;
1541-
}
1542-
1543-
const Descriptor *Desc = S.P.createDescriptor(
1544-
NewCall, *ElemT, ElemType.getTypePtr(), Descriptor::InlineDescMD,
1545-
/*IsConst=*/false, /*IsTemporary=*/false,
1546-
/*IsMutable=*/false);
1547-
Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1548-
DynamicAllocator::Form::Operator);
1534+
Block *B =
1535+
Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1536+
S.Ctx.getEvalID(), DynamicAllocator::Form::Operator);
15491537
assert(B);
1550-
1551-
S.Stk.push<Pointer>(B);
1538+
S.Stk.push<Pointer>(Pointer(B).atIndex(0));
15521539
return true;
15531540
}
15541541

15551542
assert(!ElemT);
1556-
// Structs etc.
1557-
const Descriptor *Desc =
1558-
S.P.createDescriptor(NewCall, ElemType.getTypePtr(),
1559-
IsArray ? std::nullopt : Descriptor::InlineDescMD);
15601543

1544+
// Composite arrays
15611545
if (IsArray) {
1546+
const Descriptor *Desc =
1547+
S.P.createDescriptor(NewCall, ElemType.getTypePtr(),
1548+
IsArray ? std::nullopt : Descriptor::InlineDescMD);
15621549
Block *B =
15631550
Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
15641551
DynamicAllocator::Form::Operator);
@@ -1567,10 +1554,17 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
15671554
return true;
15681555
}
15691556

1557+
// Records. Still allocate them as single-element arrays.
1558+
QualType AllocType = S.getASTContext().getConstantArrayType(
1559+
ElemType, NumElems, nullptr, ArraySizeModifier::Normal, 0);
1560+
1561+
const Descriptor *Desc =
1562+
S.P.createDescriptor(NewCall, AllocType.getTypePtr(),
1563+
IsArray ? std::nullopt : Descriptor::InlineDescMD);
15701564
Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
15711565
DynamicAllocator::Form::Operator);
15721566
assert(B);
1573-
S.Stk.push<Pointer>(B);
1567+
S.Stk.push<Pointer>(Pointer(B).atIndex(0));
15741568
return true;
15751569
}
15761570

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
176176
if (const auto *VD = Desc->asValueDecl())
177177
Base = VD;
178178
else if (const auto *E = Desc->asExpr()) {
179-
// Create a DynamicAlloc base of the right type.
180-
if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) {
181-
QualType AllocatedType;
182-
if (NewExpr->isArray()) {
183-
assert(Desc->isArray());
184-
APInt ArraySize(64, static_cast<uint64_t>(Desc->getNumElems()),
185-
/*IsSigned=*/false);
186-
AllocatedType =
187-
ASTCtx.getConstantArrayType(NewExpr->getAllocatedType(), ArraySize,
188-
nullptr, ArraySizeModifier::Normal, 0);
189-
} else {
190-
AllocatedType = NewExpr->getAllocatedType();
191-
}
179+
if (block()->isDynamic()) {
180+
QualType AllocatedType = getDeclPtr().getFieldDesc()->getDataType(ASTCtx);
192181
// FIXME: Suboptimal counting of dynamic allocations. Move this to Context
193182
// or InterpState?
194183
static int ReportedDynamicAllocs = 0;

0 commit comments

Comments
 (0)