Description
This bug gives a correctness error sv-benchmarks/c/array-memsafety/openbsd_cmemrchr-alloca_true-valid-memsafety.i
Pointers are represented as (object, offset) pairs. The back-end (bv_pointers.h) encodes these into config.ansi_c.pointer_width bit bvt's by using the top BV_ADDR_BITS (currently 8) for the object and the remaining bits for the offset. This means that if the offset uses more bits than that it will be truncated giving some really fun effects when the decode sign extends it.
It is not immediately clear how to fix this:
- Have offset be a full word and add BV_ADDR_BITS on the front. This means that pointers will no longer have the correct size.
- Another option is to make this limitation clearer by catching any offset large enough to trigger this problem. That would avoid this kind of silent mistake but its all shades of ugly.
- There might be a semi-fix in which we rely on knowing the object size to do the encoding / decoding. That way we should only get weirdness like this in cases where the program would allocate more than an addressible amount of memory. I'll see what I can do.
int main() {
int n = nondet_int();
__CPROVER_assume( (n > 0) && (n > (1 << 23)) );
int nm = n-1;
char *base = __builtin_alloca (n);
//char works = *(base + nm);
char *last = base + nm;
signed offset = __CPROVER_POINTER_OFFSET(last);
__CPROVER_assert(0 <= offset && offset < n, "range check");
return 0;
}