Skip to content

Packed union field ptr at comptime hits unreachable #19411

@Vexu

Description

@Vexu

Discovered in #19347

export fn entry() void {
    comptime testFlagsInPackedUnionAtOffset();
}
fn testFlagsInPackedUnionAtOffset() void {
    const FlagBits = packed union {
        base_flags: packed union {
            flags: packed struct(u4) {
                enable_1: bool = true,
                enable_2: bool = false,
                enable_3: bool = false,
                enable_4: bool = false,
            },
            bits: u4,
        },
        adv_flags: packed struct(u12) {
            pad: u8 = 0,
            adv: packed union {
                flags: packed struct(u4) {
                    enable_1: bool = true,
                    enable_2: bool = false,
                    enable_3: bool = false,
                    enable_4: bool = false,
                },
                bits: u4,
            },
        },
    };
    var test_bits: FlagBits = .{ .adv_flags = .{ .adv = .{ .flags = .{} } } };
    test_bits.adv_flags.adv.bits = 12;
    if ((&test_bits.adv_flags.adv.flags.enable_1).* != false) unreachable;
}
Stack trace
thread 92776 panic: reached unreachable code
Analyzing a.zig: a.zig:testFlagsInPackedUnionAtOffset
      %91 = dbg_stmt(27, 20)
      %92 = field_ptr(%67, "adv_flags") node_offset:42:11 to :42:30
      %93 = dbg_stmt(27, 30)
      %94 = field_ptr(%92, "adv") node_offset:42:11 to :42:34
      %95 = dbg_stmt(27, 34)
      %96 = field_ptr(%94, "flags") node_offset:42:11 to :42:40
      %97 = dbg_stmt(27, 40)
      %98 = field_ptr(%96, "enable_1") node_offset:42:11 to :42:49
      %99 = validate_deref(%98) node_offset:42:9 to :42:52
    > %100 = load(%98) node_offset:42:9 to :42:52
      %101 = cmp_neq(%100, @bool_false) node_offset:42:9 to :42:61
      %102 = condbr(%101, {
        %104 = dbg_stmt(27, 63)
        %105 = unreachable() node_offset:42:63 to :42:74
      }, {
        %106 = break(%103, @void_value)
      }) node_offset:42:5 to :42:74
    For full context, use the command
      zig ast-check -t a.zig

  in a.zig: a.zig:testFlagsInPackedUnionAtOffset
    > %103 = block({%91..%102}) node_offset:42:5 to :42:74
  in a.zig: a.zig:entry
    > %27 = call(.compile_time, %25, []) node_offset:14:14 to :14:46
  in a.zig: a.zig:entry
    > %24 = block_comptime({%25..%28}) node_offset:14:14 to :14:46

/home/vexu/Documents/zig/zig/src/Value.zig:1770:21: 0xa1f7b69 in fieldValue (zig)
            else => unreachable,
                    ^
/home/vexu/Documents/zig/zig/src/Sema.zig:31429:53: 0xb7ecd9e in beginComptimePtrLoad (zig)
                        .val = try tv.val.fieldValue(mod, field_index),
                                                    ^
/home/vexu/Documents/zig/zig/src/Sema.zig:38160:44: 0xb2d3d68 in pointerDerefExtra (zig)
    const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {
                                           ^
/home/vexu/Documents/zig/zig/src/Sema.zig:38131:43: 0xad63302 in pointerDeref (zig)
    const res = try sema.pointerDerefExtra(block, src, ptr_val, load_ty);
                                          ^
/home/vexu/Documents/zig/zig/src/Sema.zig:32594:34: 0xa825b93 in analyzeLoad (zig)
        if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| {
                                 ^

This test case is modified from the flags in packed union at offset test in behavior/packed-union.zig.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions