ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.15k stars 2.5k forks source link

"Segmentation fault" when compiling a piece of bad code #18556

Open zigo101 opened 8 months ago

zigo101 commented 8 months ago

Zig Version

0.12.0-dev.2159+7916cf6f8

Steps to Reproduce and Observed Behavior

const std = @import("std");

const Value = struct {
    tree: Tree,
};

const Node = struct {
    parent: *Node,
    value: Value,
};

const NodeWithFakeValue = struct {
    parent: *Node,
    value: [@sizeOf(Value)]u8 align(@alignOf(Value)), // will never be used
};

const Tree = struct {
    nullNode: *Node = undefined,
    _zero: NodeWithFakeValue = undefined,

    pub fn init(self: *Tree) void {
        self.nullNode = @ptrCast(&self._zero);
    }
};

pub fn main() !void {
    var t: Tree = undefined;
    t.init();
    std.debug.print("{}\n", .{&t});
}

Expected Behavior

The code contains self-dependency, so expect a message of that. But it ends with ”Segmentation fault“。

tiawl commented 8 months ago

Duplicate of this issue: https://github.com/ziglang/zig/issues/18346 ?

Vexu commented 8 months ago

Doesn't look related to me.

garrisonhh commented 7 months ago

here's a reduction. if you remove the unused field you get the intended error message.

const A = struct {
    unused: void,
    bad_field: [@sizeOf(A)]u8 align(@alignOf(A)),
};

pub fn main() !void {
    const a: A = undefined;
    _ = a;
}

error trace (0.12.0-dev.3153+469643940):

thread 57406 panic: reached unreachable code
Analyzing zzz/self_dep_segfault.zig: self_dep_segfault.zig:A
      %3 = decl_val("A") token_offset:4:25 to :4:26
      %4 = size_of(%3) node_offset:4:17 to :4:27
    > %5 = array_type(%4, @u8_type) node_offset:4:16 to :4:30
      %6 = break_inline(%2, %5)
    For full context, use the command
      zig ast-check -t zzz/self_dep_segfault.zig

  in zzz/self_dep_segfault.zig: self_dep_segfault.zig:main
    > %17 = as_node(%14, @undef) node_offset:8:18 to :8:27
  in lib/std/start.zig: start.zig:callMain
    > %1826 = is_non_err(%1825) 
  in lib/std/start.zig: start.zig:callMain
    > %1828 = block({%1823..%1827}) 
  in lib/std/start.zig: start.zig:callMain
    > %1774 = switch_block(%1772,
        else => {%1917, %1920},
        %1775 => {%1776..%1780},
        %1781 => {%1782..%1790},
        by_val %1791 => {%1792..%1820},
        %1821 => {%1822..%1916}) 
  in lib/std/start.zig: start.zig:callMainWithArgs
    > %1579 = call(.auto, %1577, []) 
  in lib/std/start.zig: start.zig:posixCallMainAndExit
    > %1414 = call(.auto, %1412, [
        {%1415},
        {%1416},
        {%1417},
      ]) 
  in lib/std/start.zig: start.zig:posixCallMainAndExit
    > %1411 = field_call(nodiscard .auto, %1409, "exit", [
        {%1412..%1418},
      ]) 

/home/garrison/dev/zig/lib/std/debug.zig:403:14: 0x1811a8c in assert (zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/garrison/dev/zig/src/type.zig:443:15: 0x1949b03 in fromInterned (zig)
        assert(i != .none);
              ^
/home/garrison/dev/zig/src/Sema.zig:35589:43: 0x1ee41a3 in resolveStructLayout (zig)
        const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
                                          ^
/home/garrison/dev/zig/src/Sema.zig:35465:51: 0x1bda9ec in resolveTypeLayout (zig)
        .Struct => return sema.resolveStructLayout(ty),
                                                  ^
/home/garrison/dev/zig/src/type.zig:1399:67: 0x1bd982b in abiSizeAdvanced (zig)
                        .sema => |sema| try sema.resolveTypeLayout(ty),
                                                                  ^
/home/garrison/dev/zig/src/Value.zig:535:63: 0x1bd2b67 in getUnsignedIntAdvanced (zig)
                    (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar
                                                              ^
/home/garrison/dev/zig/src/Sema.zig:2698:43: 0x1bdb99d in analyzeAsInt (zig)
    return (try val.getUnsignedIntAdvanced(mod, sema)).?;
                                          ^
/home/garrison/dev/zig/src/Sema.zig:2684:29: 0x2b7f07f in resolveInt (zig)
    return sema.analyzeAsInt(block, src, air_ref, dest_ty, reason);
                            ^
/home/garrison/dev/zig/src/Sema.zig:8379:36: 0x26d1422 in zirArrayType (zig)
    const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, .{
                                   ^
/home/garrison/dev/zig/src/Sema.zig:1015:67: 0x21dcb3f in analyzeBodyInner (zig)
            .array_type                   => try sema.zirArrayType(block, inst),
                                                                  ^
/home/garrison/dev/zig/src/Sema.zig:919:30: 0x1ee2887 in analyzeInlineBody (zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/garrison/dev/zig/src/Sema.zig:945:39: 0x1be297e in resolveInlineBody (zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/garrison/dev/zig/src/Sema.zig:36656:54: 0x283385b in semaStructFields (zig)
            const ty_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
                                                     ^
/home/garrison/dev/zig/src/Sema.zig:36253:25: 0x22e0d3d in resolveTypeFieldsStruct (zig)
    try semaStructFields(mod, sema.arena, struct_type);
                        ^
/home/garrison/dev/zig/src/Sema.zig:36188:48: 0x1eea288 in resolveTypeFields (zig)
            => try sema.resolveTypeFieldsStruct(ty_ip, ip.indexToKey(ty_ip).struct_type),
                                               ^
/home/garrison/dev/zig/src/Sema.zig:28546:31: 0x1ef5485 in coerceExtra (zig)
    try sema.resolveTypeFields(dest_ty);
                              ^
/home/garrison/dev/zig/src/Sema.zig:9979:28: 0x2b814a0 in analyzeAs (zig)
    return sema.coerceExtra(block, dest_ty, operand, src, .{ .is_ret = is_ret, .no_cast_to_comptime_int = no_cast_to_comptime_int }) catch |err| switch (err) {
                           ^
/home/garrison/dev/zig/src/Sema.zig:9936:26: 0x26d241c in zirAsNode (zig)
    return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false);
                         ^
/home/garrison/dev/zig/src/Sema.zig:1018:64: 0x21dcd16 in analyzeBodyInner (zig)
            .as_node                      => try sema.zirAsNode(block, inst),
                                                               ^
/home/garrison/dev/zig/src/Sema.zig:901:26: 0x21dbff1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/garrison/dev/zig/src/Module.zig:4518:23: 0x1ea4d5e in analyzeFnBody (zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/garrison/dev/zig/src/Module.zig:3190:32: 0x1bbcdf1 in ensureFuncBodyAnalyzed (zig)
    var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                               ^
/home/garrison/dev/zig/src/Sema.zig:32404:31: 0x285773d in ensureFuncBodyAnalyzed (zig)
    mod.ensureFuncBodyAnalyzed(func) catch |err| {
                              ^
/home/garrison/dev/zig/src/Sema.zig:36363:40: 0x22fe63b in resolveInferredErrorSet (zig)
        try sema.ensureFuncBodyAnalyzed(func_index);
                                       ^
/home/garrison/dev/zig/src/Sema.zig:32735:69: 0x27971a6 in analyzeIsNonErrComptimeOnly (zig)
                const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
                                                                    ^
/home/garrison/dev/zig/src/Sema.zig:32764:56: 0x2ba1299 in analyzeIsNonErr (zig)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
/home/garrison/dev/zig/src/Sema.zig:18946:32: 0x26e976f in zirIsNonErr (zig)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
/home/garrison/dev/zig/src/Sema.zig:1072:66: 0x21deec7 in analyzeBodyInner (zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/home/garrison/dev/zig/src/Sema.zig:5945:34: 0x2bcb3db in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/garrison/dev/zig/src/Sema.zig:5922:33: 0x2799ed7 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/garrison/dev/zig/src/Sema.zig:1589:49: 0x21ebb25 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                                ^
/home/garrison/dev/zig/src/Sema.zig:5945:34: 0x2bcb3db in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/garrison/dev/zig/src/Sema.zig:10748:45: 0x2bc1d10 in resolveProngComptime (zig)
                return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);
                                            ^
/home/garrison/dev/zig/src/Sema.zig:12900:48: 0x2bc0576 in resolveSwitchComptime (zig)
                return spa.resolveProngComptime(
                                               ^
/home/garrison/dev/zig/src/Sema.zig:12139:37: 0x26f96f2 in zirSwitchBlock (zig)
        return resolveSwitchComptime(
                                    ^
/home/garrison/dev/zig/src/Sema.zig:1095:69: 0x21dfcf3 in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                    ^
/home/garrison/dev/zig/src/Sema.zig:901:26: 0x21dbff1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/garrison/dev/zig/src/Sema.zig:7681:35: 0x28490c5 in analyzeCall (zig)
                sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                                  ^
/home/garrison/dev/zig/src/Sema.zig:6883:43: 0x26d987e in zirCall__anon_111771 (zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/garrison/dev/zig/src/Sema.zig:1029:62: 0x21dd3ea in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/garrison/dev/zig/src/Sema.zig:901:26: 0x21dbff1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/garrison/dev/zig/src/Sema.zig:7681:35: 0x28490c5 in analyzeCall (zig)
                sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                                  ^
/home/garrison/dev/zig/src/Sema.zig:6883:43: 0x26d987e in zirCall__anon_111771 (zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/garrison/dev/zig/src/Sema.zig:1029:62: 0x21dd3ea in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/garrison/dev/zig/src/Sema.zig:919:30: 0x1ee2887 in analyzeInlineBody (zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/garrison/dev/zig/src/Sema.zig:945:39: 0x1be297e in resolveInlineBody (zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/garrison/dev/zig/src/Sema.zig:7172:65: 0x2dc0977 in analyzeArg (zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/garrison/dev/zig/src/Sema.zig:7733:49: 0x2849ff6 in analyzeCall (zig)
            arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);
                                                ^
/home/garrison/dev/zig/src/Sema.zig:6883:43: 0x26daaee in zirCall__anon_111772 (zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/garrison/dev/zig/src/Sema.zig:1030:62: 0x21dd487 in analyzeBodyInner (zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/garrison/dev/zig/src/Sema.zig:901:26: 0x21dbff1 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/garrison/dev/zig/src/Module.zig:4518:23: 0x1ea4d5e in analyzeFnBody (zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/garrison/dev/zig/src/Module.zig:3190:32: 0x1bbcdf1 in ensureFuncBodyAnalyzed (zig)
    var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                               ^
/home/garrison/dev/zig/src/Compilation.zig:3505:42: 0x1bbaf2b in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/garrison/dev/zig/src/Compilation.zig:3434:30: 0x197deee in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/garrison/dev/zig/src/Compilation.zig:2191:31: 0x19795cd in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/garrison/dev/zig/src/main.zig:4439:24: 0x19a7a2f in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/garrison/dev/zig/src/main.zig:3348:17: 0x1a0ef71 in buildOutputType (zig)
    updateModule(comp, color) catch |err| switch (err) {
                ^
/home/garrison/dev/zig/src/main.zig:266:31: 0x18140cb in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .run);
                              ^
/home/garrison/dev/zig/src/main.zig:204:20: 0x1810cc4 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/garrison/dev/zig/lib/std/start.zig:511:37: 0x181074e in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7fffeb621fcd in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7fffeb621fcd` was not available, trace may be incomplete

Aborted (core dumped)
garrisonhh commented 7 months ago

hmm this segfaults as well without providing an error trace

const A = struct {
    a: A,
};

pub fn main() !void {
    const a: A = undefined;
    _ = a;
}