Skip to content

Commit d5c0cf0

Browse files
committed
implement freeze for aggregates
1 parent f6b34be commit d5c0cf0

File tree

1 file changed

+21
-24
lines changed

1 file changed

+21
-24
lines changed

ir/instr.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,34 +2518,31 @@ void Freeze::print(ostream &os) const {
25182518
os << getName() << " = freeze " << print_type(getType()) << val->getName();
25192519
}
25202520

2521-
StateValue Freeze::toSMT(State &s) const {
2522-
auto &v = s[*val];
2523-
s.resetUndefVars();
2524-
2525-
auto scalar = [&](auto &v, auto &np, auto &ty) -> StateValue {
2526-
if (np.isTrue())
2527-
return { expr(v), expr(np) };
2528-
2529-
StateValue ret_type = ty.getDummyValue(true);
2530-
expr nondet = expr::mkFreshVar("nondet", ret_type.value);
2531-
s.addQuantVar(nondet);
2532-
return { expr::mkIf(np, v, std::move(nondet)), std::move(ret_type.non_poison) };
2533-
};
2534-
2535-
// TODO: support recursive aggregates
2536-
2537-
if (getType().isAggregateType()) {
2521+
static StateValue freeze_elems(State &s, const Type &ty, const StateValue &v) {
2522+
if (auto agg = ty.getAsAggregateType()) {
25382523
vector<StateValue> vals;
2539-
auto ty = getType().getAsAggregateType();
2540-
for (unsigned i = 0, e = ty->numElementsConst(); i != e; ++i) {
2541-
if (ty->isPadding(i))
2524+
for (unsigned i = 0, e = agg->numElementsConst(); i != e; ++i) {
2525+
if (agg->isPadding(i))
25422526
continue;
2543-
auto vi = ty->extract(v, i);
2544-
vals.emplace_back(scalar(vi.value, vi.non_poison, ty->getChild(i)));
2527+
vals.emplace_back(freeze_elems(s, agg->getChild(i), agg->extract(v, i)));
25452528
}
2546-
return ty->aggregateVals(vals);
2529+
return agg->aggregateVals(vals);
25472530
}
2548-
return scalar(v.value, v.non_poison, getType());
2531+
2532+
if (v.non_poison.isTrue())
2533+
return v;
2534+
2535+
StateValue ret_type = ty.getDummyValue(true);
2536+
expr nondet = expr::mkFreshVar("nondet", ret_type.value);
2537+
s.addQuantVar(nondet);
2538+
return { expr::mkIf(v.non_poison, v.value, nondet),
2539+
std::move(ret_type.non_poison) };
2540+
}
2541+
2542+
StateValue Freeze::toSMT(State &s) const {
2543+
auto &v = s[*val];
2544+
s.resetUndefVars();
2545+
return freeze_elems(s, getType(), v);
25492546
}
25502547

25512548
expr Freeze::getTypeConstraints(const Function &f) const {

0 commit comments

Comments
 (0)