damn you clang..
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -3377,7 +3377,7 @@ static void ensure_varargs_ptr(D &data, State &s, const expr &arg_ptr) {
expr zero = expr::mkUInt(0, VARARG_BITS);
ENSURE(data.try_emplace(arg_ptr,
expr::mkUF("vararg_alive", { arg_ptr }, false),
- zero, // = next_arg
+ expr(zero), // = next_arg
expr::mkUF("vararg_num_args", { arg_ptr }, zero),
expr(false), // = va_start
!matched).second);
@@ -3442,6 +3442,9 @@ StateValue VaCopy::toSMT(State &s) const {
next_arg.add(entry.next_arg, select);
num_args.add(entry.num_args, select);
is_va_start.add(entry.va_start, move(select));
+
+ // kill aliases
+ entry.active &= ptr != dst_raw;
}
// FIXME: dst should be empty or we have a mem leak

MODIFY
ir/state.cpp
ir/state.cpp
@@ -97,8 +97,9 @@ State::VarArgsData::mkIf(const expr &cond, const VarArgsData &then,
for (auto &[ptr, entry] : then.data) {
auto other = els.data.find(ptr);
if (other == els.data.end()) {
- ret.data.try_emplace(ptr, cond && entry.alive, entry.next_arg,
- entry.num_args, entry.va_start, entry.active);
+ ret.data.try_emplace(ptr, cond && entry.alive, expr(entry.next_arg),
+ expr(entry.num_args), expr(entry.va_start),
+ expr(entry.active));
} else {
#define C(f) expr::mkIf(cond, entry.f, other->second.f)
ret.data.try_emplace(ptr, C(alive), C(next_arg), C(num_args), C(va_start),
@@ -110,8 +111,9 @@ State::VarArgsData::mkIf(const expr &cond, const VarArgsData &then,
for (auto &[ptr, entry] : els.data) {
if (then.data.count(ptr))
continue;
- ret.data.try_emplace(ptr, !cond && entry.alive, entry.next_arg,
- entry.num_args, entry.va_start, entry.active);
+ ret.data.try_emplace(ptr, !cond && entry.alive, expr(entry.next_arg),
+ expr(entry.num_args), expr(entry.va_start),
+ expr(entry.active));
}
return ret;

MODIFY
ir/state.h
ir/state.h
@@ -70,6 +70,13 @@ private:
smt::expr va_start;
smt::expr active; // false if this entry is repeated
+ VarArgsEntry() {}
+ VarArgsEntry(smt::expr &&alive, smt::expr &&next_arg, smt::expr &&num_args,
+ smt::expr &&va_start, smt::expr &&active)
+ : alive(std::move(alive)), next_arg(std::move(next_arg)),
+ num_args(std::move(num_args)), va_start(std::move(va_start)),
+ active(std::move(active)) {}
+
// FIXME: upgrade with C++20
bool operator<(const VarArgsEntry &rhs) const;
};

damn you clang..