Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error: compiler bug: generating const value for struct field '0' #6446

Closed
codehz opened this issue Sep 28, 2020 · 8 comments
Closed

error: compiler bug: generating const value for struct field '0' #6446

codehz opened this issue Sep 28, 2020 · 8 comments
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@codehz
Copy link
Contributor

codehz commented Sep 28, 2020

code:

const std = @import("std");
pub const Error = error{ WrongCode };

pub fn Base16(comptime map: *const [16]u8) type {
    return struct {
        pub fn calcSize(len: usize) usize {
            return len * 2;
        }

        pub fn encode(dst: []u8, src: []const u8) void {
            if (dst.len != calcSize(src.len)) @panic("length mismatch");
            for (src) |ch, i| {
                std.log.err(":{x}:{}{}", .{ch, [1]u8{map[(@intCast(usize, ch) >> 4) % 0xF]}, [1]u8{map[@intCast(usize, ch) % 0xF]}});
                dst[i * 2] = map[(@intCast(usize, ch) >> 4) % 0xF];
                dst[i * 2 + 1] = map[@intCast(usize, ch) % 0xF];
            }
        }

        fn getOrigin(ch: u8) ?u8 {
            inline for (map) |x, i| {
                if (x == ch) return @intCast(u8, i);
            }
            return null;
        }

        pub fn decode(dst: []u8, src: []const u8) Error!void {
            if (src.len != calcSize(dst.len)) @panic("length mismatch");
            var rch: u8 = undefined;
            for (src) |ch, i| {
                const origin = getOrigin(ch) orelse return Error.WrongCode;
                if (i % 2 == 0) {
                    rch = origin << 4;
                } else {
                    rch |= origin;
                }
            }
        }
    };
}

const standard_base16 = Base16("0123456789ABCDEF");

test "encode" {
    var dst: [8]u8 = undefined;
    standard_base16.encode(&dst, "0123");
    std.log.err("{}", .{dst});
    std.testing.expectEqual(@as(*const [8]u8, &dst).*, "30313233".*);
}

PS: I know there is a mistake in % 0xF (it should be % 0x10)

@travisstaloch
Copy link
Sponsor Contributor

travisstaloch commented Sep 28, 2020

On latest master (0.6.0+e60939bfa), looks like the error in formatting. I think this is a minimal repro. Seems to only happen when within a function, not if the moved into the test. Also, only happens as the second format argument.

const std = @import("std");
test "seg fault" {
    foo("0123");
}
pub fn foo(src: []const u8) void {   
    const ch = src[0];
    // comment out this line and it compiles
    std.debug.print("{}:{}", .{ch, [1]u8{ch}});
    // No segfault
    std.debug.print("{}", .{[1]u8{ch}});
}

Stack trace of the error:

$ gdb zig
...
(gdb) run test tmp3.zig
Starting program: ...zig/zig/build/zig test tmp3.zig

Program received signal SIGBUS, Bus error.
0x00007ffff0e87dbd in get_pointer_to_type_extra2(CodeGen*, ZigType*, bool, bool, PtrLen, unsigned int, unsigned int, unsigned int, bool, unsigned int, InferredStructField*, ZigValue*) ()
(gdb) bt
#0  0x00007ffff0e87dbd in get_pointer_to_type_extra2(CodeGen*, ZigType*, bool, bool, PtrLen, unsigned int, unsigned int, unsigned int, bool, unsigned int, InferredStructField*, ZigValue*) ()
#1  0x00007ffff0e889ee in ensure_const_val_repr(IrAnalyze*, CodeGen*, AstNode*, ZigValue*, ZigType*) ()
#2  0x00007ffff0dbaa68 in gen_const_val(CodeGen*, ZigValue*, char const*) [clone .isra.0] ()
#3  0x00007ffff0dba578 in gen_const_val_ptr(CodeGen*, ZigValue*, char const*) [clone .isra.0] ()
#4  0x00007ffff0dba6ce in gen_const_val(CodeGen*, ZigValue*, char const*) [clone .isra.0] ()
#5  0x00007ffff0dbe63b in ir_llvm_value(CodeGen*, IrInstGen*) ()
#6  0x00007ffff0dbfce6 in ir_render_struct_field_ptr(CodeGen*, IrExecutableGen*, IrInstGenStructFieldPtr*) [clone .isra.0] ()
#7  0x00007ffff0dcb2cd in ir_render_instruction(CodeGen*, IrExecutableGen*, IrInstGen*) [clone .isra.0] ()
#8  0x00007ffff0dcc43b in do_code_gen(CodeGen*) ()
#9  0x00007ffff0dcdfcc in codegen_build_and_link(CodeGen*) ()
#10 0x00007ffff0da3c27 in main0(int, char**) ()
#11 0x00007ffff0d10c87 in main ()
(gdb) 

@travisstaloch
Copy link
Sponsor Contributor

and this produces a different segfault which is caught by zig:

const std = @import("std");
test "seg fault" {
    foo("0123");
}
pub fn foo(src: []const u8) void {   
    const ch = src[0];
    std.debug.print("{}", .{[1]u8{ch}});
}
$ zig test tmp3.zig 
Test [1/1] test "seg fault"... Segmentation fault at address 0x201e20
/tmp/tmp3.zig:7:35: 0x206cc8 in foo (test)
    std.debug.print("{}", .{[1]u8{ch}});
                                  ^
/tmp/tmp3.zig:3:8: 0x205866 in test "seg fault" (test)
    foo("0123");
       ^
.../zig/zig/build/lib/zig/std/special/test_runner.zig:61:28: 0x22d751 in std.special.main (test)
        } else test_fn.func();
                           ^
.../zig/zig/build/lib/zig/std/start.zig:272:37: 0x20701d in std.start.posixCallMainAndExit (test)
            const result = root.main() catch |err| {
                                    ^
.../zig/zig/build/lib/zig/std/start.zig:143:5: 0x206d5f in std.start._start (test)
    @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});

@Vexu Vexu added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Sep 29, 2020
@Vexu Vexu added this to the 0.8.0 milestone Sep 29, 2020
@LemonBoy
Copy link
Contributor

LemonBoy commented Sep 29, 2020

Minimal repro:

pub export fn _start() void {
    foo("0123");
}

pub fn foo(src: []const u8) void {
    const ch = src[0];
    const x = .{ ch, [1]u8{ch} };
}

const builtin = @import("builtin");
pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
    while (true) {}
}

It's the usual result-loc bullshit that cannot be debugged. If you break on ir_resolve_result you'll see that the array field is treated as it were comptime-known and so is the whole tuple. This trips up the codegen phase that tries to render this constant value that doesn't really know.

@ghost
Copy link

ghost commented Sep 29, 2020

Could this be the same bug as #3915 ?

@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
@wooster0
Copy link
Contributor

wooster0 commented Mar 31, 2022

I don't know if this is helpful or still relevant but I'm hitting the same error on 0.9.1 with this code. I think this is slightly more reduced than the previous ones:

fn getFalse() bool {
    return false;
}

fn getZero() i8 {
    return 0;
}

pub fn main() void {
    // It compiles if either of these 2 calls are inlined manually.
    // If you inline only `getFalse()`, it segfaults.
    // If you inline only `getZero()`, it does not.
    // If you inline `getFalse()` and `getZero()`, it does not either.
    const x = .{ getFalse(), .{ @intCast(u8, getZero()) } };
    _ = x;
}
./x.zig:14:26: error: compiler bug: generating const value for struct field '0'
    const x = .{ getFalse(), .{ @intCast(u8, getZero()) } };
                         ^

@egasimus
Copy link

Also hitting this on 0.9.1 and can't find a workaround. Rep(r)o

@wooster0
Copy link
Contributor

@egasimus try it with the latest version. I think it's fixed on stage2.

@Vexu
Copy link
Member

Vexu commented Mar 28, 2024

Fixed in master.

@Vexu Vexu closed this as completed Mar 28, 2024
@Vexu Vexu modified the milestones: 0.15.0, 0.12.0 Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

7 participants