Skip to content

Commit c2f0f64

Browse files
committed
further work on growable objects (#1227)
1 parent 16db40c commit c2f0f64

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

ir/instr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4056,13 +4056,13 @@ StateValue GEP::toSMT(State &s) const {
40564056
// FIXME: not implemented for physical pointers
40574057
s.addUB(ptr.isLogical());
40584058
s.doesApproximation("gep inbounds of phy ptr", !ptr.isLogical(), true);
4059-
inbounds_np.add(ptr.inbounds(false));
4059+
inbounds_np.add(ptr.inbounds(false, true));
40604060
}
40614061

40624062
expr offset_sum = expr::mkUInt(0, bits_for_offset);
40634063
for (auto &[sz, idx] : offsets) {
40644064
auto &[v, np] = idx;
4065-
auto multiplier = expr::mkUInt(sz, bits_for_offset);
4065+
auto multiplier = expr::mkUInt(sz, offset_sum);
40664066
auto val = v.sextOrTrunc(bits_for_offset);
40674067
auto inc = multiplier * val;
40684068

@@ -4100,7 +4100,7 @@ StateValue GEP::toSMT(State &s) const {
41004100
non_poison.add(np);
41014101

41024102
if (inbounds)
4103-
inbounds_np.add(ptr.inbounds(false));
4103+
inbounds_np.add(ptr.inbounds(false, true));
41044104
}
41054105

41064106
if (inbounds) {
@@ -4114,7 +4114,7 @@ StateValue GEP::toSMT(State &s) const {
41144114

41154115
// try to simplify the pointer
41164116
if (all_zeros.isFalse())
4117-
ptr.inbounds(true);
4117+
ptr.inbounds(true, true);
41184118
}
41194119

41204120
return { std::move(ptr).release(), non_poison() };

ir/memory.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ expr Memory::hasStored(const Pointer &p, const expr &bytes) const {
13741374
}
13751375
}
13761376

1377-
void Memory::record_store(const Pointer &p, const smt::expr &bytes) {
1377+
void Memory::record_store(const Pointer &p, const expr &bytes) {
13781378
assert(has_initializes_attr);
13791379

13801380
auto is_local = p.isLocal();
@@ -1618,7 +1618,7 @@ void Memory::mkAxioms(const Memory &tgt) const {
16181618
state->addAxiom(q.isHeapAllocated().implies(q.blockAlignment() == align));
16191619
}
16201620

1621-
for (unsigned bid = has_null_block; bid < num_nonlocals_src; ++bid) {
1621+
for (unsigned bid = skip_null(); bid < num_nonlocals_src; ++bid) {
16221622
Pointer p(*this, bid, false);
16231623
state->addAxiom(p.getAllocType().ult(Pointer::NUM_ALLOC_TYPES));
16241624
state->addAxiom(p.blockSize().ule(p.blockMaxSize()));
@@ -1666,15 +1666,15 @@ void Memory::mkAxioms(const Memory &tgt) const {
16661666
expr::mkUInt(0, 1).concat(last.extract(bits_ptr_address-2, 0)))
16671667
: addr != last);
16681668
} else {
1669-
sz = p1.blockSizeAligned().zextOrTrunc(bits_ptr_address);
1669+
sz = p1.blockMaxSizeAligned().zextOrTrunc(bits_ptr_address);
16701670
state->addAxiom(
16711671
Pointer::hasLocalBit()
16721672
// don't spill to local addr section
16731673
? (addr + sz).sign() == 0
16741674
: addr.add_no_uoverflow(sz));
16751675
}
16761676

1677-
state->addAxiom(p1.blockSize()
1677+
state->addAxiom(p1.blockMaxSize()
16781678
.round_up_bits_no_overflow(p1.blockAlignment()));
16791679

16801680
if (num_nonlocals > max_quadratic_disjoint)
@@ -1686,7 +1686,7 @@ void Memory::mkAxioms(const Memory &tgt) const {
16861686
continue;
16871687
Pointer p2(tgt, bid2, false);
16881688
state->addAxiom(disjoint(addr, sz, align, p2.getAddress(),
1689-
p2.blockSizeAligned()
1689+
p2.blockMaxSizeAligned()
16901690
.zextOrTrunc(bits_ptr_address),
16911691
p2.blockAlignment()));
16921692
}
@@ -1958,7 +1958,7 @@ Memory::mkCallState(const string &fnname, bool nofree, unsigned num_ptr_args,
19581958
}
19591959

19601960
st.non_local_sizes.resize(num_nonlocals_src);
1961-
for (unsigned bid = has_null_block; bid < num_nonlocals_src; ++bid) {
1961+
for (unsigned bid = skip_null(); bid < num_nonlocals_src; ++bid) {
19621962
Pointer p(*this, bid, false);
19631963
if (!p.isGrowableAlloc().isFalse()) {
19641964
expr max_size = p.blockMaxSize();
@@ -2117,9 +2117,9 @@ void Memory::setState(const Memory::CallState &st,
21172117

21182118
// TODO: function calls can also free local objects passed by argument
21192119

2120-
for (unsigned bid = has_null_block; bid < num_nonlocals_src; ++bid) {
2120+
for (unsigned bid = skip_null(); bid < num_nonlocals_src; ++bid) {
21212121
Pointer p(*this, bid, false);
2122-
expr growable = p.isGrowableAlloc();
2122+
expr growable = p.isGrowableAlloc() && access.canWrite(MemoryAccess::Other);
21232123
if (!growable.isFalse())
21242124
non_local_blk_size.replace(
21252125
p.getShortBid(),

ir/pointer.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Pointer::Pointer(const Memory &m, const expr &bid, const expr &offset,
7878
}
7979

8080
Pointer::Pointer(const Memory &m, const char *var_name,
81-
const ParamAttrs &attr, const std::set<smt::expr> &fn_vars)
81+
const ParamAttrs &attr, const set<expr> &fn_vars)
8282
: m(const_cast<Memory&>(m)) {
8383
auto ty = expr::mkUInt(0, bitsShortBid() + bits_for_offset);
8484
vector<expr> vars(fn_vars.begin(), fn_vars.end());
@@ -332,7 +332,7 @@ expr Pointer::blockSize() const {
332332
expr Pointer::blockMaxSize() const {
333333
return
334334
mkIf_fold(getAllocType() == GROWABLE,
335-
getValue("blk_max_size", m.local_blk_size, m.non_local_blk_size,
335+
getValue("blk_max_size", m.local_blk_size, {},
336336
expr::mkUInt(0, bits_size_t)),
337337
blockSize());
338338
}
@@ -351,6 +351,16 @@ expr Pointer::blockSizeAlignedOffsetT() const {
351351
return bits_for_offset > bits_size_t ? sz.zextOrTrunc(bits_for_offset) : sz;
352352
}
353353

354+
expr Pointer::blockMaxSizeAligned() const {
355+
return
356+
blockMaxSize().round_up_bits(blockAlignment().zextOrTrunc(bits_size_t));
357+
}
358+
359+
expr Pointer::blockMaxSizeAlignedOffsetT() const {
360+
expr sz = blockMaxSizeAligned();
361+
return bits_for_offset > bits_size_t ? sz.zextOrTrunc(bits_for_offset) : sz;
362+
}
363+
354364
expr Pointer::leftoverSize() const {
355365
auto off = getOffsetSizet();
356366
auto sz = blockSizeOffsetT();
@@ -447,22 +457,23 @@ expr Pointer::isInboundsOf(const Pointer &block, const expr &bytes0,
447457
(addr + bytes).ule(block_addr + block_size);
448458
}
449459

450-
expr Pointer::isInbounds(bool strict) const {
460+
expr Pointer::isInbounds(bool strict, bool max_size) const {
451461
auto offset = getOffsetSizet();
452-
auto size = blockSizeAlignedOffsetT();
462+
auto size = max_size ? blockMaxSizeAlignedOffsetT()
463+
: blockSizeAlignedOffsetT();
453464
expr ret = strict ? offset.ult(size) : offset.ule(size);
454465
if (bits_for_offset <= bits_size_t) // implied
455466
ret &= !offset.isNegative();
456467
return ret;
457468
}
458469

459-
expr Pointer::inbounds(bool simplify_ptr) {
470+
expr Pointer::inbounds(bool simplify_ptr, bool max_size) {
460471
if (!simplify_ptr)
461-
return isInbounds(false);
472+
return isInbounds(false, max_size);
462473

463474
DisjointExpr<expr> ret(expr(false)), all_ptrs;
464475
for (auto &[ptr_expr, domain] : DisjointExpr<expr>(p, 3)) {
465-
expr inb = Pointer(m, ptr_expr).isInbounds(false);
476+
expr inb = Pointer(m, ptr_expr).isInbounds(false, max_size);
466477
if (!inb.isFalse())
467478
all_ptrs.add(ptr_expr, domain);
468479
ret.add(std::move(inb), domain);

ir/pointer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class Pointer {
9292
smt::expr blockSizeOffsetT() const; // to compare with offsets
9393
smt::expr blockSizeAligned() const;
9494
smt::expr blockSizeAlignedOffsetT() const; // to compare with offsets
95+
smt::expr blockMaxSizeAligned() const;
96+
smt::expr blockMaxSizeAlignedOffsetT() const;
9597

9698
smt::expr leftoverSize() const;
9799

@@ -118,8 +120,8 @@ class Pointer {
118120
bool is_phy) const;
119121
smt::expr isInboundsOf(const Pointer &block, const smt::expr &bytes,
120122
bool is_phy) const;
121-
smt::expr isInbounds(bool strict) const;
122-
smt::expr inbounds(bool simplify_ptr = false);
123+
smt::expr isInbounds(bool strict, bool max_size = false) const;
124+
smt::expr inbounds(bool simplify_ptr = false, bool max_size = false);
123125

124126
smt::expr blockAlignment() const; // log(bits)
125127
smt::expr isBlockAligned(uint64_t align, bool exact = false) const;

0 commit comments

Comments
 (0)