Skip to content

Commit 338f681

Browse files
committed
fn calls: track which blocks are freed
1 parent 1b7531c commit 338f681

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

ir/memory.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,23 +1769,22 @@ Memory::CallState Memory::CallState::mkIf(const expr &cond,
17691769
}
17701770
}
17711771
ret.writes_block = expr::mkIf(cond, then.writes_block, els.writes_block);
1772+
ret.frees_block = expr::mkIf(cond, then.frees_block, els.frees_block);
17721773
ret.writes_args = expr::mkIf(cond, then.writes_args, els.writes_args);
17731774
ret.non_local_liveness = expr::mkIf(cond, then.non_local_liveness,
17741775
els.non_local_liveness);
17751776
return ret;
17761777
}
17771778

17781779
expr Memory::CallState::operator==(const CallState &rhs) const {
1779-
if (non_local_liveness.isValid() != rhs.non_local_liveness.isValid())
1780-
return false;
1781-
if (!non_local_liveness.isValid())
1782-
return true;
1783-
17841780
expr ret = non_local_liveness == rhs.non_local_liveness;
1785-
for (unsigned i = 0, e = non_local_block_val.size(); i != e; ++i) {
1786-
ret &= non_local_block_val[i] == rhs.non_local_block_val[i];
1781+
if (non_local_block_val.size() == rhs.non_local_block_val.size()) {
1782+
for (unsigned i = 0, e = non_local_block_val.size(); i != e; ++i) {
1783+
ret &= non_local_block_val[i] == rhs.non_local_block_val[i];
1784+
}
17871785
}
17881786
ret &= writes_block == rhs.writes_block;
1787+
ret &= frees_block == rhs.frees_block;
17891788
if (writes_args.isValid())
17901789
ret &= writes_args == rhs.writes_args;
17911790
return ret;
@@ -1796,6 +1795,8 @@ Memory::mkCallState(const string &fnname, bool nofree, unsigned num_ptr_args,
17961795
const SMTMemoryAccess &access) {
17971796
assert(has_fncall);
17981797
CallState st;
1798+
st.non_local_liveness = mk_liveness_array();
1799+
st.frees_block = expr::mkUInt(0, st.non_local_liveness);
17991800

18001801
{
18011802
unsigned num_blocks = 1;
@@ -1843,12 +1844,18 @@ Memory::mkCallState(const string &fnname, bool nofree, unsigned num_ptr_args,
18431844
st.writes_args
18441845
= expr::mkFreshVar("writes_args", expr::mkUInt(0, num_ptr_args));
18451846

1846-
st.non_local_liveness = mk_liveness_array();
1847-
if (num_nonlocals_src && !nofree)
1847+
if (num_nonlocals_src && !nofree) {
1848+
auto may_free = access.canAccess(MemoryAccess::Other) ||
1849+
access.canAccess(MemoryAccess::Inaccessible);
1850+
st.frees_block
1851+
= mkIf_fold(may_free,
1852+
expr::mkFreshVar("frees_block", st.non_local_liveness),
1853+
st.frees_block);
18481854
st.non_local_liveness
1849-
= mkIf_fold(only_write_inaccess,
1850-
st.non_local_liveness,
1851-
expr::mkFreshVar("blk_liveness", st.non_local_liveness));
1855+
= mkIf_fold(may_free,
1856+
expr::mkFreshVar("blk_liveness", st.non_local_liveness),
1857+
st.non_local_liveness);
1858+
}
18521859

18531860
return st;
18541861
}
@@ -1923,11 +1930,13 @@ void Memory::setState(const Memory::CallState &st,
19231930
expr one = expr::mkUInt(1, num_nonlocals);
19241931
expr zero = expr::mkUInt(0, num_nonlocals);
19251932
expr mask = always_nowrite(0) ? one : zero;
1926-
expr may_free = access.canAccess(MemoryAccess::Other);
1933+
expr may_free = access.canAccess(MemoryAccess::Other) ||
1934+
access.canAccess(MemoryAccess::Inaccessible);
19271935

19281936
for (unsigned bid = always_nowrite(0); bid < num_nonlocals; ++bid) {
19291937
expr heap = Pointer(*this, bid, false).isHeapAllocated();
1930-
mask = mask | expr::mkIf(heap && may_free && !is_fncall_mem(bid),
1938+
mask = mask | expr::mkIf(heap && may_free && !is_fncall_mem(bid) &&
1939+
st.frees_block.extract(bid, bid) == 1,
19311940
zero,
19321941
one << expr::mkUInt(bid, one));
19331942
}

ir/memory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ class Memory {
246246
smt::expr non_local_liveness;
247247
smt::expr writes_block;
248248
smt::expr writes_args;
249+
smt::expr frees_block;
249250

250251
public:
251252
smt::expr writes(unsigned idx) const;

tests/alive-tv/memory/inaccessiblememonly2.srctgt.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
; ERROR: Source is more defined than target
2+
13
define i4 @src(ptr %p) {
24
%v = load i4, ptr %p
35
call void @fn()

0 commit comments

Comments
 (0)