zig
zig copied to clipboard
Segfault with comptime functions
Zig Version
0.12.0-dev.1830+779b8e259
Steps to Reproduce and Observed Behavior
The file:
const std = @import ("std");
const e = enum (u9)
{
// From my understanding those 2 lines are the same but the second one does not work:
// const U: u9 = 255;
const U: @typeInfo (@This ()).Enum.tag_type = std.math.maxInt (@Type (.{ .Int = .{ .signedness = .unsigned, .bits = @typeInfo (@typeInfo (@This ()).Enum.tag_type).Int.bits - 1 }}));
a = U + 1,
};
test "test"
{
std.debug.print ("{}\n", .{ @intFromEnum (e.a) });
}
The output:
$ zig test test.zig
Segmentation fault (core dumped)
Expected Behavior
$ zig test test.zig
Test [1/1] test.test... 256
All 1 tests passed.
Am I missing something ? Thank you.
Crashing instead of producing an error is a compiler bug, but note that @typeInfo(@This()) contains the values of all of the enum tags, which requires resolving the value of U first, which requires resolving the value of @typeInfo(@This()) before that, so it's not clear how this would be implemented otherwise.
Putting the U declaration outside the enum and changing @typeInfo(@This()) into @typeInfo(e) triggers an error: dependency loop detected. So that is right, the "Expected Behavior" section in my first message should contain this error message.
debug trace on 0.12.0-dev.1839+461f9c283:
thread 916074 panic: reached unreachable code
Analyzing empty.zig: empty.zig:e.U
%9 = extended(this())
> %10 = type_info(%9)
%11 = field_val(%10, "Enum")
%12 = field_val(%11, "tag_type")
%13 = as_node(@type_type, %12)
%14 = decl_ref("std")
%15 = field_ptr(%14, "math")
%16 = dbg_stmt(1, 64)
%17 = field_call(.compile_time, %15, "maxInt", [
{
%18 = validate_struct_init_result_ty(@type_info_type)
%19 = struct_init_field_type(@type_info_type, Int)
%20 = validate_struct_init_result_ty(%19)
%21 = struct_init_field_type(%19, signedness)
%22 = enum_literal("unsigned")
%23 = struct_init_field_type(%19, bits)
%24 = extended(this())
%25 = type_info(%24)
%26 = field_val(%25, "Enum")
%27 = field_val(%26, "tag_type")
%28 = type_info(%27)
%29 = field_val(%28, "Int")
%30 = field_val(%29, "bits")
%31 = sub(%30, @one)
%32 = struct_init([%21, %22], [%23, %31])
%33 = struct_init([%19, %32])
%34 = extended(reify(%33))
%35 = break_inline(%17, %34)
},
])
%36 = as_node(%13, %17)
%37 = break_inline(%8, %36)
For full context, use the command
zig ast-check -t empty.zig
in empty.zig: empty.zig:e
> %38 = decl_val("U")
in empty.zig: empty.zig:e
> %5 = extended(enum_decl(parent, {
[95] U line(3) hash(85c87214a7ed3acf0990f64ed2321976): %8 = ...
}, %7, {%6..%41}, {
a = %40,
})
in empty.zig: empty.zig:test.test
> %57 = decl_val("e")
in empty.zig: empty.zig:test.test
> %52 = field_call(nodiscard .auto, %49, "print", [
{%53, %54},
{%55..%62},
])
in empty.zig: empty.zig:test.test
> %44 = block({%45..%65})
/home/dr/zig/lib/std/debug.zig:342:14: 0x610760c in assert (zig)
if (!ok) unreachable; // assertion failure
^
/home/dr/zig/src/InternPool.zig:3715:11: 0x6180dbd in indexToKey (zig)
assert(index != .none);
^
/home/dr/zig/src/Sema.zig:17359:51: 0x6b278b6 in zirTypeInfo (zig)
mod.intern_pool.indexToKey(enum_type.values.get(ip)[i]).int,
^
/home/dr/zig/src/Sema.zig:1096:66: 0x678824c in analyzeBodyInner (zig)
.type_info => try sema.zirTypeInfo(block, inst),
^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/home/dr/zig/src/Module.zig:3681:50: 0x64fb4ac in semaDecl (zig)
const result_ref = (try sema.analyzeBodyBreak(&block_scope, @ptrCast(body))).?.operand;
^
/home/dr/zig/src/Module.zig:3255:32: 0x62655fd in ensureDeclAnalyzed (zig)
break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
^
/home/dr/zig/src/Sema.zig:31666:27: 0x70e8f39 in ensureDeclAnalyzed (zig)
mod.ensureDeclAnalyzed(decl_index) catch |err| {
^
/home/dr/zig/src/Sema.zig:31711:32: 0x71814ca in analyzeDeclRefInner (zig)
try sema.ensureDeclAnalyzed(decl_index);
^
/home/dr/zig/src/Sema.zig:31626:50: 0x70acf35 in analyzeDeclVal (zig)
const decl_ref = try sema.analyzeDeclRefInner(decl_index, false);
^
/home/dr/zig/src/Sema.zig:6380:31: 0x6af78ed in zirDeclVal (zig)
return sema.analyzeDeclVal(block, src, decl);
^
/home/dr/zig/src/Sema.zig:1038:65: 0x678579c in analyzeBodyInner (zig)
.decl_val => try sema.zirDeclVal(block, inst),
^
/home/dr/zig/src/Sema.zig:916:30: 0x6a85cf8 in analyzeBody (zig)
_ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/home/dr/zig/src/Sema.zig:3005:33: 0x6b76274 in zirEnumDecl (zig)
try sema.analyzeBody(&enum_block, body);
^
/home/dr/zig/src/Sema.zig:1227:64: 0x678d271 in analyzeBodyInner (zig)
.enum_decl => try sema.zirEnumDecl( block, extended, inst),
^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/home/dr/zig/src/Module.zig:3681:50: 0x64fb4ac in semaDecl (zig)
const result_ref = (try sema.analyzeBodyBreak(&block_scope, @ptrCast(body))).?.operand;
^
/home/dr/zig/src/Module.zig:3255:32: 0x62655fd in ensureDeclAnalyzed (zig)
break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
^
/home/dr/zig/src/Sema.zig:31666:27: 0x70e8f39 in ensureDeclAnalyzed (zig)
mod.ensureDeclAnalyzed(decl_index) catch |err| {
^
/home/dr/zig/src/Sema.zig:31711:32: 0x71814ca in analyzeDeclRefInner (zig)
try sema.ensureDeclAnalyzed(decl_index);
^
/home/dr/zig/src/Sema.zig:31626:50: 0x70acf35 in analyzeDeclVal (zig)
const decl_ref = try sema.analyzeDeclRefInner(decl_index, false);
^
/home/dr/zig/src/Sema.zig:6380:31: 0x6af78ed in zirDeclVal (zig)
return sema.analyzeDeclVal(block, src, decl);
^
/home/dr/zig/src/Sema.zig:1038:65: 0x678579c in analyzeBodyInner (zig)
.decl_val => try sema.zirDeclVal(block, inst),
^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/home/dr/zig/src/Sema.zig:882:50: 0x70a8a53 in resolveBody (zig)
const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
^
/home/dr/zig/src/Sema.zig:6981:59: 0x75d7c65 in analyzeArg (zig)
const uncoerced_arg = try sema.resolveBody(block, arg_body, zir_call.call_inst);
^
/home/dr/zig/src/Sema.zig:7904:49: 0x75daa59 in instantiateGenericCall (zig)
const arg_ref = try args_info.analyzeArg(sema, block, arg_index, param_ty, generic_owner_ty_info, func);
^
/home/dr/zig/src/Sema.zig:7212:40: 0x70af7e8 in analyzeCall (zig)
if (sema.instantiateGenericCall(
^
/home/dr/zig/src/Sema.zig:6692:43: 0x6af42c0 in zirCall__anon_95837 (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/dr/zig/src/Sema.zig:1029:62: 0x6785083 in analyzeBodyInner (zig)
.field_call => try sema.zirCall(block, inst, .field),
^
/home/dr/zig/src/Sema.zig:5853:34: 0x7166ee7 in resolveBlockBody (zig)
if (sema.analyzeBodyInner(child_block, body)) |_| {
^
/home/dr/zig/src/Sema.zig:5836:33: 0x6bb79af in zirBlock (zig)
return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
^
/home/dr/zig/src/Sema.zig:1577:49: 0x6795897 in analyzeBodyInner (zig)
break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
^
/home/dr/zig/src/Sema.zig:916:30: 0x6a85cf8 in analyzeBody (zig)
_ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/home/dr/zig/src/Module.zig:4616:21: 0x6761480 in analyzeFnBody (zig)
sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
^
/home/dr/zig/src/Module.zig:3324:40: 0x64e147d in ensureFuncBodyAnalyzed (zig)
var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
^
/home/dr/zig/src/Compilation.zig:3761:42: 0x64df84d in processOneJob (zig)
module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
^
/home/dr/zig/src/Compilation.zig:3698:30: 0x62b1738 in performAllTheWork (zig)
try processOneJob(comp, work_item, main_progress_node);
^
/home/dr/zig/src/Compilation.zig:2505:31: 0x62acf92 in update (zig)
try comp.performAllTheWork(main_progress_node);
^
/home/dr/zig/src/main.zig:4283:24: 0x62dd6a2 in updateModule (zig)
try comp.update(main_progress_node);
^
/home/dr/zig/src/main.zig:3684:17: 0x6300262 in buildOutputType (zig)
updateModule(comp) catch |err| switch (err) {
^
/home/dr/zig/src/main.zig:284:31: 0x6109ad7 in mainArgs (zig)
return buildOutputType(gpa, arena, args, .zig_test);
^
/home/dr/zig/src/main.zig:222:20: 0x6106ad5 in main (zig)
return mainArgs(gpa, arena, args);
^
/home/dr/zig/lib/std/start.zig:585:37: 0x6106556 in main (zig)
const result = root.main() catch |err| {
^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7f318cf5f0cf in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:360:3: 0x7f318cf5f188 in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x61061a4 in ??? (???)
???:?:?: 0x0 in ??? (???)