@@ -766,6 +766,27 @@ expr Pointer::isHeapAllocated() const {
766766 return getAllocType ().extract (1 , 1 ) == 1 ;
767767}
768768
769+ static expr at_least_same_offseting (const Pointer &p1, const Pointer &p2) {
770+ expr size = p1.blockSizeOffsetT ();
771+ expr off = p1.getOffsetSizet ();
772+ expr size2 = p2.blockSizeOffsetT ();
773+ expr off2 = p2.getOffsetSizet ();
774+ return
775+ expr::mkIf (p1.isHeapAllocated (),
776+ p1.getAllocType () == p2.getAllocType () &&
777+ off == off2 && size == size2,
778+
779+ expr::mkIf (off.sge (0 ),
780+ off2.sge (0 ) &&
781+ expr::mkIf (off.ule (size),
782+ off2.ule (size2) && off2.uge (off) &&
783+ (size2 - off2).uge (size - off),
784+ off2.ugt (size2) && off == off2 &&
785+ size2.uge (size)),
786+ // maintains same dereferenceability before/after
787+ off == off2 && size2.uge (size)));
788+ }
789+
769790expr Pointer::refined (const Pointer &other) const {
770791 bool is_asm = other.m .isAsmMode ();
771792 auto [p1l, d1] = toLogicalLocal ();
@@ -774,12 +795,16 @@ expr Pointer::refined(const Pointer &other) const {
774795 // This refers to a block that was malloc'ed within the function
775796 expr local = d2 && p2l.isLocal ();
776797 local &= p1l.getAllocType () == p2l.getAllocType ();
777- local &= p1l.blockSize () == p2l.blockSize ();
778- local &= p1l.getOffset () == p2l.getOffset ();
798+ if (is_asm) {
799+ local &= at_least_same_offseting (p1l, p2l);
800+ } else {
801+ local &= p1l.blockSize () == p2l.blockSize ();
802+ local &= p1l.getOffset () == p2l.getOffset ();
803+ }
779804 local &= p1l.isBlockAlive ().implies (p2l.isBlockAlive ());
780805 // Attributes are ignored at refinement.
781806
782- if (is_asm)
807+ if (! is_asm)
783808 local &= isLogical () == other.isLogical ();
784809
785810 // TODO: this induces an infinite loop
@@ -802,30 +827,13 @@ expr Pointer::fninputRefined(const Pointer &other, set<expr> &undef,
802827 bool is_asm = other.m .isAsmMode ();
803828 auto [p1l, d1] = toLogicalLocal ();
804829 auto [p2l, d2] = other.toLogicalLocal ();
805- expr size = p1l.blockSizeOffsetT ();
806- expr off = p1l.getOffsetSizet ();
807- expr size2 = p2l.blockSizeOffsetT ();
808- expr off2 = p2l.getOffsetSizet ();
809830
810831 // TODO: check block value for byval_bytes
811832 if (!byval_bytes.isZero ())
812833 return true ;
813834
814- expr local
815- = expr::mkIf (p1l.isHeapAllocated (),
816- p1l.getAllocType () == p2l.getAllocType () &&
817- off == off2 && size == size2,
818-
819- expr::mkIf (off.sge (0 ),
820- off2.sge (0 ) &&
821- expr::mkIf (off.ule (size),
822- off2.ule (size2) && off2.uge (off) &&
823- (size2 - off2).uge (size - off),
824- off2.ugt (size2) && off == off2 &&
825- size2.uge (size)),
826- // maintains same dereferenceability before/after
827- off == off2 && size2.uge (size)));
828- local = d2 && (p2l.isLocal () || p2l.isByval ()) && local;
835+ expr local = d2 && (p2l.isLocal () || p2l.isByval ()) &&
836+ at_least_same_offseting (p1l, p2l);
829837
830838 if (is_asm)
831839 local &= isLogical () == other.isLogical ();
0 commit comments