The refutation manager is removing a true bug from the following program:
typedef struct o p;
struct o {
struct {
} s;
};
void q(*r, p2) {
r < p2;
}
void k(l, node) {
struct {
p *node;
} * n, *nodep, path[sizeof(void)];
path->node = l;
for (n = path; node != l;) {
q(node, n->node);
nodep = n;
}
if (nodep)
n[1].node->s; // warning: Dereference of undefined pointer value
}The problem is that the following constraint:
(conj_$1{struct o *}) - (reg_$3<int * r>): [-9223372036854775808, 0]is encoded as:
(and (bvuge (bvsub $1 $3) #x8000000000000000)
(bvule (bvsub $1 $3) #x0000000000000000))The issue is that unsigned comparisons (bvuge and bvule) are being generated instead of signed comparisons (bvsge and bvsle).
When generating the expressions:
(conj_$1{p *}) - (reg_$3<int * r>) >= -9223372036854775808and
(conj_$1{p *}) - (reg_$3<int * r>) <= 0both -9223372036854775808 and 0 are casted to pointer type and LTy->isSignedIntegerOrEnumerationType() in Z3ConstraintManager::getZ3BinExpr only checks if the type is signed, not if it's a pointer.
~
I created this PR to discuss the solution, as this change is currently breaking some regressions (Analysis/ptr-arith.c).
I'll add the test to this PR as soon as I can remove all the unrelated warning that are being produced in the example (incompatible types, discarded results, etc).