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

compiler crash: const_ptr_pointee_unchecked_no_isf. #7019

Closed
vrischmann opened this issue Nov 7, 2020 · 3 comments · Fixed by #7024
Closed

compiler crash: const_ptr_pointee_unchecked_no_isf. #7019

vrischmann opened this issue Nov 7, 2020 · 3 comments · Fixed by #7024
Labels
bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@vrischmann
Copy link
Contributor

Hello,

using Zig version 0.6.0+5430642fa I'm getting the following crash:

Assertion failed at ../src/stage1/ir.cpp:873 in const_ptr_pointee_unchecked_no_isf. This is a bug in the Zig compiler.
/home/vincent/dev/devtools/zig/src/stage1.zig:167:5: 0x9e008c in stage2_panic (zig1)
    @panic(ptr[0..len]);
    ^
../src/stage1/util.cpp:20:17: 0x13b8f4d in zig_panic (../src/stage1/util.cpp)
../src/stage1/util_base.hpp:53:18: 0x14059f1 in zig_assert (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:873:5: 0x1407f6d in const_ptr_pointee_unchecked_no_isf (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:894:46: 0x14080db in const_ptr_pointee_unchecked (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:10602:48: 0x1428681 in const_ptr_pointee (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:22898:48: 0x14557e1 in ir_analyze_instruction_field_ptr (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:31885:52: 0x14781b7 in ir_analyze_instruction_base (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:32208:65: 0x14791b8 in ir_analyze (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:13651:38: 0x1433a7f in ir_eval_const_value (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:20479:43: 0x144c39a in ir_analyze_fn_call (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:20916:43: 0x144e15a in ir_analyze_fn_call_src (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:21163:42: 0x144f03f in ir_analyze_instruction_call (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:31887:47: 0x14781cf in ir_analyze_instruction_base (../src/stage1/ir.cpp)
../src/stage1/ir.cpp:32208:65: 0x14791b8 in ir_analyze (../src/stage1/ir.cpp)
../src/stage1/analyze.cpp:4987:44: 0x14c5d56 in analyze_fn_ir (../src/stage1/analyze.cpp)
../src/stage1/analyze.cpp:5103:18: 0x14c6309 in analyze_fn_body (../src/stage1/analyze.cpp)
../src/stage1/analyze.cpp:5215:28: 0x14c6b16 in semantic_analyze (../src/stage1/analyze.cpp)
../src/stage1/codegen.cpp:9258:25: 0x13dfab8 in gen_root_source (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:9307:20: 0x13dfe0c in codegen_build_object (../src/stage1/codegen.cpp)
../src/stage1/stage1.cpp:126:25: 0x13b4d0e in zig_stage1_build_object (../src/stage1/stage1.cpp)
/home/vincent/dev/devtools/zig/src/stage1.zig:139:32: 0xccd2e4 in Module.build_object (zig1)
        zig_stage1_build_object(mod);
                               ^
/home/vincent/dev/devtools/zig/src/Compilation.zig:2799:31: 0xb3e8f7 in Compilation.updateStage1Module (zig1)
    stage1_module.build_object();
                              ^
/home/vincent/dev/devtools/zig/src/Compilation.zig:1386:36: 0xafcad3 in Compilation.performAllTheWork (zig1)
            self.updateStage1Module(main_progress_node) catch |err| {
                                   ^
/home/vincent/dev/devtools/zig/src/Compilation.zig:1088:31: 0xaf6d87 in Compilation.update (zig1)
    try self.performAllTheWork();
                              ^
/home/vincent/dev/devtools/zig/src/main.zig:1843:20: 0xaaf096 in main.updateModule (zig1)
    try comp.update();
                   ^
/home/vincent/dev/devtools/zig/src/main.zig:1710:21: 0xa062ec in main.buildOutputType (zig1)
    try updateModule(gpa, comp, zir_out_path, hook);
                    ^
/home/vincent/dev/devtools/zig/src/main.zig:165:31: 0x9def66 in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/vincent/dev/devtools/zig/src/stage1.zig:45:24: 0x9de77e in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;

with this code (it's a little long sorry, I was unable to make a shorter reproducer):

const builtin = @import("builtin");
const std = @import("std");
const mem = std.mem;

pub const BindMarker = union(enum) {
    Type: type,
    NoType: void,
};

pub const ParsedQuery = struct {
    const Self = @This();

    bind_markers: [128]BindMarker,
    nb_bind_markers: usize,

    query: [1024]u8,
    query_size: usize,

    fn from(comptime query: []const u8) Self {
        const State = enum {
            Start,
            BindMarker,
            BindMarkerType,
        };

        comptime var buf: [query.len]u8 = undefined;
        comptime var pos = 0;
        comptime var state = .Start;

        comptime var current_bind_marker_type: [256]u8 = undefined;
        comptime var current_bind_marker_type_pos = 0;

        comptime var parsed_query: ParsedQuery = undefined;
        parsed_query.nb_bind_markers = 0;

        inline for (query) |c, i| {
            switch (state) {
                .Start => switch (c) {
                    '?' => {
                        state = .BindMarker;
                        buf[pos] = c;
                    },
                    else => {
                        buf[pos] = c;
                    },
                },
                .BindMarker => switch (c) {
                    '{' => {
                        state = .BindMarkerType;
                        current_bind_marker_type_pos = 0;
                    },
                    else => {
                        @compileError("a bind marker start (the character ?) must be followed by a bind marker type, eg {integer}");
                    },
                },
                .BindMarkerType => switch (c) {
                    '}' => {
                        state = .Start;

                        const typ = parsed_query.parseType(current_bind_marker_type[0..current_bind_marker_type_pos]);

                        parsed_query.bind_markers[parsed_query.nb_bind_markers].Type = BindMarker{ .Type = typ };
                        parsed_query.nb_bind_markers += 1;
                    },
                    else => {
                        current_bind_marker_type[current_bind_marker_type_pos] = c;
                        current_bind_marker_type_pos += 1;
                    },
                },
                else => {
                    @compileError("invalid state " ++ @tagName(state));
                },
            }

            pos += 1;
        }

        mem.copy(u8, &parsed_query.query, &buf);
        parsed_query.query_size = pos;

        return parsed_query;
    }

    fn parseType(comptime self: *Self, type_info: []const u8) type {
        if (type_info.len <= 0) @compileError("invalid type info " ++ type_info);

        // Integer
        if (mem.eql(u8, "usize", type_info)) return usize;
        if (mem.eql(u8, "isize", type_info)) return isize;

        if (type_info[0] == 'u' or type_info[0] == 'i') {
            return @Type(builtin.TypeInfo{
                .Int = builtin.TypeInfo.Int{
                    .is_signed = type_info[0] == 'i',
                    .bits = std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch {
                        @compileError("invalid type info " ++ type_info);
                    },
                },
            });
        }

        @compileError("invalid type info " ++ type_info);
    }

    fn getQuery(comptime self: *Self) []const u8 {
        return self.query[0..self.query_size];
    }
};

test "parsed query" {
    const query = "INSERT INTO user(id, name, age) VALUES(?{i32}, ?{usize}, ?{})";

    comptime var parsed_query = ParsedQuery.from(query);
    std.debug.print("parsed query: {}\n", .{parsed_query});
    std.debug.print("parsed query: {}\n", .{parsed_query.getQuery()});
}
@vrischmann
Copy link
Contributor Author

The crash is caused by this line:

parsed_query.bind_markers[parsed_query.nb_bind_markers].Type = BindMarker{ .Type = typ };

@LemonBoy
Copy link
Contributor

LemonBoy commented Nov 7, 2020

parsed_query.bind_markers[parsed_query.nb_bind_markers].Type = BindMarker{ .Type = typ };

You want this instead:
parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{ .Type = typ };

@vrischmann
Copy link
Contributor Author

Damn, I should have seen that. Thanks.

LemonBoy added a commit to LemonBoy/zig that referenced this issue Nov 7, 2020
The code rightfully assumes the union_val object to be fully initialized.

Closes ziglang#7019
LemonBoy added a commit to LemonBoy/zig that referenced this issue Nov 8, 2020
Alternative fix for ziglang#7019, perhaps a bit cleaner and more in line with
how the other types are handled.
@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior stage1 The process of building from source via WebAssembly and the C backend. labels Nov 11, 2020
@andrewrk andrewrk added this to the 0.7.1 milestone Nov 11, 2020
LemonBoy added a commit to LemonBoy/zig that referenced this issue Nov 17, 2020
The code rightfully assumes the union_val object to be fully initialized.

Closes ziglang#7019
LemonBoy added a commit to LemonBoy/zig that referenced this issue Nov 17, 2020
The code rightfully assumes the union_val object to be fully initialized.

Closes ziglang#7019
Vexu pushed a commit that referenced this issue Nov 18, 2020
The code rightfully assumes the union_val object to be fully initialized.

Closes #7019
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

Successfully merging a pull request may close this issue.

3 participants