| 15 | class Memory; |
| 16 | |
| 17 | class Pointer { |
| 18 | Memory &m; |
| 19 | |
| 20 | // [0, padding, bid, offset, attributes (1 bit for each)] -- logical pointer |
| 21 | // [1, padding, address, attributes] -- physical pointer |
| 22 | // The top bit of bid is 1 if the block is local, 0 otherwise. |
| 23 | // A local memory block is a memory block that is |
| 24 | // allocated by an instruction during the current function call. This does |
| 25 | // not include allocated blocks from a nested function call. A heap-allocated |
| 26 | // block can also be a local memory block. |
| 27 | // Otherwise, a pointer is pointing to a non-local block, which can be either |
| 28 | // of global variable, heap, or a stackframe that is not this function call. |
| 29 | // The lowest bits represent whether the pointer value came from a nocapture/ |
| 30 | // readonly argument. If block is local, is-readonly or is-nocapture cannot |
| 31 | // be 1. |
| 32 | // TODO: missing support for address space |
| 33 | smt::expr p; |
| 34 | |
| 35 | smt::expr getValue(const char *name, const smt::FunctionExpr &local_fn, |
| 36 | const smt::FunctionExpr &nonlocal_fn, |
| 37 | const smt::expr &ret_type, bool src_name = false) const; |
| 38 | |
| 39 | public: |
| 40 | Pointer(const Memory &m, const smt::expr &bid, const smt::expr &offset, |
| 41 | const smt::expr &attr); |
| 42 | Pointer(const Memory &m, const char *var_name, const ParamAttrs &attr); |
| 43 | Pointer(const Memory &m, smt::expr p); |
| 44 | Pointer(const Memory &m, unsigned bid, bool local, smt::expr attr = {}); |
| 45 | Pointer(const Memory &m, const smt::expr &bid, const smt::expr &offset, |
| 46 | const ParamAttrs &attr = {}); |
| 47 | |
| 48 | static Pointer mkPhysical(const Memory &m, const smt::expr &addr); |
| 49 | static Pointer mkPhysical(const Memory &m, const smt::expr &addr, |
| 50 | const smt::expr &attr); |
| 51 | |
| 52 | Pointer(const Pointer &other) noexcept = default; |
| 53 | Pointer(Pointer &&other) noexcept = default; |
| 54 | void operator=(Pointer &&rhs) noexcept { p = std::move(rhs.p); } |
| 55 | |
| 56 | // returns (log-ptr, domain of inboundness) |
| 57 | std::pair<Pointer, smt::expr> |
| 58 | findLogicalLocalPointer(const smt::expr &addr) const; |
| 59 | std::pair<Pointer, smt::expr> toLogicalLocal() const; |
| 60 | |
| 61 | static smt::expr mkLongBid(const smt::expr &short_bid, bool local); |
| 62 | static smt::expr mkUndef(State &s); |
| 63 | |
| 64 | static unsigned totalBits(); |
| 65 | static unsigned bitsShortBid(); |
| 66 | static unsigned bitsShortOffset(); |
| 67 | static unsigned zeroBitsShortOffset(); |
| 68 | static bool hasLocalBit(); |
| 69 | |
| 70 | smt::expr isLogical() const; |
| 71 | |
| 72 | smt::expr isLocal(bool simplify = true) const; |
| 73 | smt::expr isConstGlobal() const; |
| 74 | smt::expr isWritableGlobal() const; |
no outgoing calls
no test coverage detected