Skip to content

Commit c177507

Browse files
authored
[clang][Interp] Cleaning up FIXMEs added during ArrayInitLoopExpr implementation. (#70053)
This patch removes the two `FIXME`s that were added with patches related to the expression mentioned in the title.
1 parent f13aac6 commit c177507

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,21 +1056,17 @@ bool ByteCodeExprGen<Emitter>::VisitArrayInitLoopExpr(
10561056
const ArrayInitLoopExpr *E) {
10571057
assert(Initializing);
10581058
assert(!DiscardResult);
1059+
1060+
// We visit the common opaque expression here once so we have its value
1061+
// cached.
1062+
if (!this->discard(E->getCommonExpr()))
1063+
return false;
1064+
10591065
// TODO: This compiles to quite a lot of bytecode if the array is larger.
10601066
// Investigate compiling this to a loop.
1061-
10621067
const Expr *SubExpr = E->getSubExpr();
1063-
const Expr *CommonExpr = E->getCommonExpr();
10641068
size_t Size = E->getArraySize().getZExtValue();
10651069

1066-
// If the common expression is an opaque expression, we visit it
1067-
// here once so we have its value cached.
1068-
// FIXME: This might be necessary (or useful) for all expressions.
1069-
if (isa<OpaqueValueExpr>(CommonExpr)) {
1070-
if (!this->discard(CommonExpr))
1071-
return false;
1072-
}
1073-
10741070
// So, every iteration, we execute an assignment here
10751071
// where the LHS is on the stack (the target array)
10761072
// and the RHS is our SubExpr.
@@ -1107,13 +1103,13 @@ bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
11071103
return false;
11081104

11091105
// Here the local variable is created but the value is removed from the stack,
1110-
// so we put it back, because the caller might need it.
1106+
// so we put it back if the caller needs it.
11111107
if (!DiscardResult) {
11121108
if (!this->emitGetLocal(SubExprT, *LocalIndex, E))
11131109
return false;
11141110
}
11151111

1116-
// FIXME: Ideally the cached value should be cleaned up later.
1112+
// This is cleaned up when the local variable is destroyed.
11171113
OpaqueExprs.insert({E, *LocalIndex});
11181114

11191115
return true;

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
374374
if (!Idx)
375375
return;
376376
this->Ctx->emitDestroy(*Idx, SourceInfo{});
377+
removeStoredOpaqueValues();
377378
}
378379

379380
/// Overriden to support explicit destruction.
@@ -382,6 +383,7 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
382383
return;
383384
this->emitDestructors();
384385
this->Ctx->emitDestroy(*Idx, SourceInfo{});
386+
removeStoredOpaqueValues();
385387
this->Idx = std::nullopt;
386388
}
387389

@@ -403,10 +405,29 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
403405
if (!Local.Desc->isPrimitive() && !Local.Desc->isPrimitiveArray()) {
404406
this->Ctx->emitGetPtrLocal(Local.Offset, SourceInfo{});
405407
this->Ctx->emitRecordDestruction(Local.Desc);
408+
removeIfStoredOpaqueValue(Local);
406409
}
407410
}
408411
}
409412

413+
void removeStoredOpaqueValues() {
414+
if (!Idx)
415+
return;
416+
417+
for (const Scope::Local &Local : this->Ctx->Descriptors[*Idx]) {
418+
removeIfStoredOpaqueValue(Local);
419+
}
420+
}
421+
422+
void removeIfStoredOpaqueValue(const Scope::Local &Local) {
423+
if (const auto *OVE =
424+
llvm::dyn_cast_if_present<OpaqueValueExpr>(Local.Desc->asExpr())) {
425+
if (auto It = this->Ctx->OpaqueExprs.find(OVE);
426+
It != this->Ctx->OpaqueExprs.end())
427+
this->Ctx->OpaqueExprs.erase(It);
428+
};
429+
}
430+
410431
/// Index of the scope in the chain.
411432
std::optional<unsigned> Idx;
412433
};

0 commit comments

Comments
 (0)