Very similar to #1498 (sorry!)
type xlen : Int = config base.xlen
constraint xlen >= 1
function identity(x : bits(xlen)) -> bits(xlen) = x
constraint xlen <= 32
function main() -> unit = {
let x : bits(xlen) = ones();
print_endline(bits_str(identity(x)));
print_endline(bits_str(identity(x)));
}
The problem is it generates this code for identity():
void zidentity(lbits *z8zE2, lbits zx)
{
__label__ end_function_7, end_block_exception_8, end_function_15;
(*(z8zE2)) = zx;
end_function_7: ;
goto end_function_15;
end_block_exception_8: ;
goto end_function_15;
end_function_15: ;
}
So you end up with both the input and output pointing to the same mpz_t and then it all falls apart.
In this small example it segfaults, in our real code it unfortunately resulted in random zeros where there shouldn't be zeros - took me quite a while to track that down!