You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No error. I checked the offsets with the debug logs and they are correct. Without mem.copy the program works.
Even if not, the program should crash at comptime.
If comptime fails (ie due to versatility of stage1), it should crash instead of writing the crash data into the binary that is being linked.
Actual Behavior
Output of the broken comptime execution is written into the resulting elf binary (on Linux) stripped by the nonvisual parts:
{ ... }ELF/proc/self/exe.debug_info.debug_abbrev.debug_str.debug_line.debug_rangessentinel mismatch
attempt to cast negative value to unsigned integerPanicked during a panic. Aborting.
Unable to dump stack trace: Unable to open debug info: {s}
ZIG_DEBUG_COLORNO_COLORTERMdumbexact division produced remainderUnable to dump stack trace: {s}
shift amount is greater than the type size{s}:{d}:{d}0x{x} in {s} ({s})unexpected errno: {d}
Segmentation fault at address 0x{x}
Illegal instruction at address 0x{x}
Bus error at address 0x{x}
{d}
{s}
Unable to dump stack trace: Unable to open debug info: {s}
Most likely the failures are caused by one or multiple offset-by-1 error. Speculatively there is missing/errorneous handling of the result and llvm doing bad stuff, but debugging is needed.
(And unfortunately I dont have time for this in the next month.)
The text was updated successfully, but these errors were encountered:
matu3ba
added
the
bug
Observed behavior contradicts documented or intended behavior
label
Feb 17, 2022
There's actually a bug in your program here. comptime vars are not mutable at runtime, and are put into .rodata after semantic analysis. This test case tries to perform the mem.copy - mutating buf- at runtime. The reason that the compiler doesn't catch it is a little subtle. Consider this code:
test {
comptimevarx: u32=undefined;
constp=&x;
@compileLog(@TypeOf(p));
p.*=runtimeVal();
}
The assignment of p.* here (correctly) gives a compilation error, since Sema expands the assignment at comptime (because p is comptime-known) and realises that p.* can only be assigned at comptime. However, what does the @compileLog print? Well, even if it's only usable at comptime, p is still a perfectly valid mutable pointer: so it has type *u32. Here's the problem: what happens if we pass p into a runtime function?
Disaster strikes! Because p isn't comptime-known within the body of runtimeSet, it never realises that it's only comptime-mutable, Type checking succeeds, the binary compiles, but it segfaults at runtime because p points to read-only data.
I'm not 100% sure what the correct solution looks like here. I think it would probably be to demote runtime-immutable pointers to const pointers when passed through to runtime code; that means when they're passed as a non-comptime parameter to a non-inline function, or when being assigned to a global.
EDIT: even simpler trigger! We can make the pointer runtime-known simply by putting it in a runtime var.
test {
comptimevarx: u32=0;
varp=&x; // p is now runtime-known!p.*=runtimeVal(); // segfault
}
fnruntimeVal() u32 {
return42;
}
mlugg
added a commit
to mlugg/zig
that referenced
this issue
Mar 17, 2023
Zig Version
0.10.0-dev.787+5aa35f62c
Steps to Reproduce
Run
Inspect with an editor the binary
comptimeMiscompilation
File
comptimeMiscompilation.zig
:Expected Behavior
mem.copy
the program works.Actual Behavior
Output of the broken comptime execution is written into the resulting elf binary (on Linux) stripped by the nonvisual parts:
Output is
Most likely the failures are caused by one or multiple offset-by-1 error. Speculatively there is missing/errorneous handling of the result and llvm doing bad stuff, but debugging is needed.
(And unfortunately I dont have time for this in the next month.)
The text was updated successfully, but these errors were encountered: