Example code:
test "coerced allowzero" {
var p: ?* u32 = undefined;
var q: ?*allowzero u32 = undefined;
p = @intToPtr(*u32, 4);
q = p; // segfaults here
}
Note that if either p or q is not optional, there's no issue.
The big problem here is that ir_analyze_cast calls types_match_const_cast_only on the two types at hand,?*T and ?*allowzero T, recursively and concludes that both at the optional-level and at the pointer-level the cast is legal.
Such a cast produces a CastOpNoop that, on the codegen side, simply tries to bitcast the value between the two types without any care about the low-level representation of the two being different.
without any care about the low-level representation of the two being different.
I thought optional pointers were just ordinary pointers under the hood with a bit of compiler-type checking on top? How are their low level representations any different?
I thought optional pointers were just ordinary pointers under the hood with a bit of compiler-type checking on top? How are their low level representations any different?
The idea is to encode the absence of a value with null as it's usually not allowed by pointers... unless you specify allowzero. In that case you cannot pull this trick anymore and the optional type becomes something like this:
const Opt = struct {
ptr: *allowzero u32,
empty: u1,
};
@LemonBoy Ah -- Thanks. What is an allowzero optional pointer even supposed to mean, though? As you say, null is how we encode the absence of a value, which by design is, naturally, 0. So why isn't 'empty' above superfluous in general?
What is an allowzero optional pointer even supposed to mean, though?
Not all the address spaces are born equal :) on some systems the zero address is addressable.
Even on x86, zero is addressable - in my Zig-based kernel though, the byte at zero isn't usable because I was running into a segfault - possibly this one, actually - when using allowzero, and I figured one byte wasn't worth it.
Most helpful comment
Not all the address spaces are born equal :) on some systems the zero address is addressable.