-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Compiler crash: runtime-conditional break/return inside inline loop #2727
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
Comments
I can't run this one windows but on Linux I get
|
Thanks for confirming it's not Windows specific! |
I am having this same issue in the following code snippet, so I'm leaving it here to see if it is useful at all. The backtrace is basically the same. // T is any type
const info = switch (@typeInfo(T)) {
.Struct => |i| i,
else => @compileError("not a struct"),
};
// json is std.json.ValueTree
const json_object = switch (json.root) {
.Object => |o| o,
else => return error.JsonNotObject,
};
inline for (info.fields) |field| {
// This if causes the segfault when `T` has more than one field,
// but works when there is one field, or if the else branch does not have a return
const field_value = if (json_object.getValue(field.name)) |value| value else {
return error.JsonMissingField;
};
} It seems that this happens when there is a chance of an early return within an inline for, probably related (or the same issue) as #2908. zig version is |
This also appears to happen with a regular non-error const ResultType = union(enum) {
Alpha: u32,
Beta: u32,
};
test "foo" {
inline for ([2]u32{ 1, 7 }) |field| {
var result = ResultType{ .Alpha = 7 };
switch (result) {
.Alpha => {},
.Beta => {},
}
}
}
zig version |
Interestingly, adding an const ResultType = struct {
tag: u2,
Alpha: u32,
Beta: u32,
};
test "foo" {
inline for ([2]u32{ 1, 7 }) |field| {
var result = ResultType{ .tag = 1, .Alpha = 7, .Beta = undefined };
if (result.tag == 1) {} else unreachable;
}
} so perhaps this has something to do with the 'exhaustiveness' of these ifs. |
I haven't done any real work on the compiler, but would be more than willing to set aside time to look into this. Any tips on how to get started looking into a bug like this? |
@pixelherodev this might a particularly difficult bug to start with as a contributor. Here's where we are collecting tips on how to do stage1 ir.cpp work: https://github.com/ziglang/zig/wiki/FAQ#are-there-any-good-examples-of-advanced-internals-development-with-zig-specifically-stage1-bug-fixes You might look for Confirmed that this is still an issue in master branch. |
Can also confirm that this happens in an inline while, not just inline for, and only when there's a possibility of early branching (so a somewhat usable workaround is to set a bool and check it after the inline while. Interestingly, despite using comptime comparisons, if I remove the comptime var index = 0;
while (index < @memberCount(RefactorSettings)) : (index += 1) {
...
} works, but if the while loop is made inline, the compiler crashes. |
I take that back; of course it doesn't work, and I'm surprised it compiled. It works if the only argument you use is the first one - that is, if index doesn't need to increment. Incrementing has, of course, no effect at runtime, so anything else, even just an invalid argument that's not in the structure, and it completely fails. |
another repro on latest master 0.5.0+c522699f2 (Mon 20 Jan 2020) test "inline while break bug repro" {
inline for ([2]u8{ 0, 0 }) |_| {
var x = false;
if (x) {} else break;
}
} produces $ zig test test1.zig
Code Generation [1/918] Segmentation fault at address 0x0 Adding the |
Here's a reproduction involving a labelled block: pub fn main() void {
blk: {
inline for ("hello") |_| {
var x = true;
if (x) break :blk;
}
}
} |
I think this issue should be renamed to something more general like "Compiler crash: runtime-conditional break/return inside inline loop" |
I'm hitting this too. I first hit it with serialization code with an inline for, and I stripped it down to code that's nearly identical to above examples:
|
Seems to be fixed somewhere between 0.10.0-dev.4060+61aaef0b0 and 0.10.0-dev.4179+884979278 |
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
Closes ziglang#2622 Closes ziglang#2727 Closes ziglang#6047 Closes ziglang#6947 Closes ziglang#6656
I'm building using
zig 0.4.0+fcc0728
on 64 bit Windows 10, built from source in Release mode.The following file run through
zig test
causes Zig to exit with no output and only empty files written to thezig-cache
:The exit code, according to an
echo %errorlevel%
, is-1073741819
. The Windows Event Viewer has the following log:The test input is seemingly minimal. It doesn't crash with only one/zero elements, it doesn't crash if the
return
is removed, replaced with other code, or moved to the other branch (thoughbreak
also causes it). It doesn't crash with a regularif
/else
. It doesn't crash if replaced withtry
or withcatch
.The text was updated successfully, but these errors were encountered: