@@ -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
17781779expr 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 }
0 commit comments