Zig: Segfault when coercing optional pointers to optional allowzero pointers

Created on 16 Dec 2019  路  6Comments  路  Source: ziglang/zig

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.

bug stage1

Most helpful comment

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.

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

S0urc3C0de picture S0urc3C0de  路  3Comments

jorangreef picture jorangreef  路  3Comments

andrewrk picture andrewrk  路  3Comments

fengb picture fengb  路  3Comments

daurnimator picture daurnimator  路  3Comments