Skip to content

Commit f6b34be

Browse files
committed
fix #815: crash when using vectors and returned paramter attr
1 parent 1be5635 commit f6b34be

File tree

6 files changed

+50
-6
lines changed

6 files changed

+50
-6
lines changed

ir/instr.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,6 +2836,19 @@ check_ret_attributes(State &s, StateValue &&sv, const Type &t,
28362836
return check_return_value(s, std::move(sv), t, attrs, true);
28372837
}
28382838

2839+
static void eq_val_rec(State &s, const Type &t, const StateValue &a,
2840+
const StateValue &b) {
2841+
if (auto agg = t.getAsAggregateType()) {
2842+
for (unsigned i = 0, e = agg->numElementsConst(); i != e; ++i) {
2843+
if (agg->isPadding(i))
2844+
continue;
2845+
eq_val_rec(s, agg->getChild(i), agg->extract(a, i), agg->extract(b, i));
2846+
}
2847+
return;
2848+
}
2849+
s.addUB(a == b);
2850+
}
2851+
28392852
StateValue Return::toSMT(State &s) const {
28402853
StateValue retval;
28412854

@@ -2851,12 +2864,8 @@ StateValue Return::toSMT(State &s) const {
28512864
if (attrs.has(FnAttrs::NoReturn))
28522865
s.addUB(expr(false));
28532866

2854-
if (auto *val_returned = s.getFn().getReturnedInput()) {
2855-
// LangRef states that return type must be valid operands for bitcasts,
2856-
// which cannot be aggregate type.
2857-
assert(!dynamic_cast<AggregateType *>(&val->getType()));
2858-
s.addUB(retval == s[*val_returned]);
2859-
}
2867+
if (auto &val_returned = s.getReturnedInput())
2868+
eq_val_rec(s, getType(), retval, *val_returned);
28602869

28612870
s.addReturn(std::move(retval));
28622871
return {};

ir/state.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,12 @@ void State::finishInitializer() {
997997
is_initialization_phase = false;
998998
}
999999

1000+
void State::saveReturnedInput() {
1001+
assert(isSource());
1002+
if (auto *ret = getFn().getReturnedInput())
1003+
returned_input = (*this)[*ret];
1004+
}
1005+
10001006
expr State::sinkDomain() const {
10011007
auto I = predecessor_data.find(&f.getSinkBB());
10021008
if (I == predecessor_data.end())
@@ -1047,6 +1053,8 @@ void State::syncSEdataWithSrc(const State &src) {
10471053
for (auto &itm : glbvar_bids)
10481054
itm.second.second = false;
10491055

1056+
returned_input = src.returned_input;
1057+
10501058
fn_call_data = src.fn_call_data;
10511059
inaccessiblemem_bids = src.inaccessiblemem_bids;
10521060
memory.syncWithSrc(src.returnMemory());

ir/state.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ class State {
123123
// Global variables' memory block ids & Memory::alloc has been called?
124124
std::unordered_map<std::string, std::pair<unsigned, bool>> glbvar_bids;
125125

126+
// The value of a 'returned' input
127+
std::optional<StateValue> returned_input;
128+
126129
// temp state
127130
const BasicBlock *current_bb = nullptr;
128131
CurrentDomain domain;
@@ -252,6 +255,11 @@ class State {
252255
const auto& getQuantVars() const { return quantified_vars; }
253256
const auto& getFnQuantVars() const { return fn_call_qvars; }
254257

258+
void saveReturnedInput();
259+
const std::optional<StateValue>& getReturnedInput() const {
260+
return returned_input;
261+
}
262+
255263
smt::expr sinkDomain() const;
256264
Memory returnMemory() const { return *return_memory(); }
257265

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define <2 x i4> @src(<2 x i4> %0) {
2+
ret <2 x i4> %0
3+
}
4+
5+
define <2 x i4> @tgt(<2 x i4> returned %0) {
6+
ret <2 x i4> %0
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; ERROR: Value mismatch
2+
3+
define <2 x i4> @src(<2 x i4> %0) {
4+
ret <2 x i4> %0
5+
}
6+
7+
define <2 x i4> @tgt(<2 x i4> returned %0) {
8+
ret <2 x i4> zeroinitializer
9+
}

util/symexec.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ void sym_exec(State &s) {
3636
}
3737
}
3838

39+
if (s.isSource())
40+
s.saveReturnedInput();
41+
3942
s.exec(Value::voidVal);
4043

4144
bool first = true;

0 commit comments

Comments
 (0)