| 796 | } |
| 797 | |
| 798 | expr Pointer::refined(const Pointer &other) const { |
| 799 | bool is_asm = other.m.isAsmMode(); |
| 800 | auto [p1l, d1] = toLogicalLocal(); |
| 801 | auto [p2l, d2] = other.toLogicalLocal(); |
| 802 | |
| 803 | // This refers to a block that was malloc'ed within the function |
| 804 | expr local = d2 && p2l.isLocal(); |
| 805 | local &= p1l.getAllocType() == p2l.getAllocType(); |
| 806 | if (is_asm) { |
| 807 | local &= at_least_same_offseting(p1l, p2l, true); |
| 808 | } else { |
| 809 | local &= p1l.blockSize() == p2l.blockSize(); |
| 810 | local &= p1l.getOffset() == p2l.getOffset(); |
| 811 | } |
| 812 | local &= p1l.isBlockAlive().implies(p2l.isBlockAlive()); |
| 813 | // Attributes are ignored at refinement. |
| 814 | |
| 815 | if (!is_asm) |
| 816 | local &= isLogical() == other.isLogical(); |
| 817 | |
| 818 | // TODO: this induces an infinite loop |
| 819 | //local &= block_refined(other); |
| 820 | |
| 821 | expr nonlocal = is_asm ? getAddress() == other.getAddress() : *this == other; |
| 822 | expr is_local = d1 && p1l.isLocal(); |
| 823 | |
| 824 | // short-circuit to avoid the constraint below: |
| 825 | // addr == 0 ? addr' == 0 : addr == addr' |
| 826 | if (is_asm && is_local.isFalse()) |
| 827 | return nonlocal; |
| 828 | |
| 829 | return expr::mkIf(isNull(), other.isNull(), |
| 830 | expr::mkIf(is_local, local, nonlocal)); |
| 831 | } |
| 832 | |
| 833 | expr Pointer::fninputRefined(const Pointer &other, set<expr> &undef, |
| 834 | const expr &byval_bytes) const { |
nothing calls this directly
no test coverage detected