Wrong resolution of a generic struct reference causes a crash #21328
Labels
Bug
This tag is applied to issues which reports bugs.
Comptime
Features processed during compile time, like $if, $for, $env etc
Unit: cgen
Bugs/feature requests, that are related to the default C generating backend.
Describe the bug
Generic function with a struct reference argument gets called with the argument cast to a wrong pointer type.
I reduced the problem to a small script which prints a part of a HAR file. There's a generic function, which accesses fields of various structs recursively:
When the field
log
of the structHar
is processed, it's cast to a wrong pointer (struct reference type), as demonstrated with testing scripts further below:The structs are nested like this:
Har { HarLog { HarEntry { HarResponse { HarContent } } } }
.Details
A reduced HAR file:
Can be deserialised to the following (also reduced) structs:
And processed by the following generic methods:
The compiler will perform:
There're more details in the steps to reproduce the problem below.
Reproduction Steps
Download all files from https://gist.github.com/prantlf/efaf649625af24223994de180088e104 to one directory. Run the
vsh
files to observe the behaviour described below.Execution of
crash-ref.vsh
:The first problem became visible when
show_struct
was called with the value ofHar.log
. Generics resolvedHar.log
toHarContent
instead of toHarLog
:Printing the first field survived, interpreting some memory as
i64
:Printing the second field crashed, interpreting some memory as
string
and getting a null pointer:The last text printed was
string: "
. Printing the string value and the trailing"
was interrupted by the wrong memory access.Expected Behavior
When a generic method is called with the type of a struct field, the compiler should resolve the type properly and call the right function:
Current Behavior
The compiler picks a wrong type. It might be a coincidence;
HarContent
is the first struct declared in the test script:Possible Solution
I wish I knew :-)
Additional Information/Context
I wasn't able to reduce the code any further while still keeping the bug triggered. Performing any of the three changes below made the script
crash-ref.vsh
succeed:Reduce struct nesting level. For example, if I modify
crash-ref.vsh
to passHarLog
instead ofHar
, the code will succeed:Let us remove the reference to pass the structs by value:
This version of the script -
succeed-value.vsh
- succeeds and prints the correct contents of all structs:Declaring the struct arguments mutable -
fail-mut.vsh
, fails in the compiler. It shows that the compiler mixes a struct with a pointer to the struct:V version
V 0.4.5 dbf48ea
Environment details (OS name and version, etc.)
V full version: V 0.4.5 27cc277.dbf48ea
OS: macos, macOS, 14.4.1, 23E224
Processor: 12 cpus, 64bit, little endian, Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
getwd: /Users/prantlf/Sources/github/crash
vexe: /usr/local/Cellar/vlang/0.4.5/libexec/v
vexe mtime: 2024-04-21 10:51:55
vroot: OK, value: /usr/local/Cellar/vlang/0.4.5/libexec
VMODULES: OK, value: /Users/prantlf/.vmodules
VTMP: OK, value: /tmp/v_501
Git version: git version 2.44.0
Git vroot status: weekly.2024.13-194-gdbf48eaa
.git/config present: true
CC version: Apple clang version 15.0.0 (clang-1500.3.9.4)
thirdparty/tcc status: thirdparty-macos-amd64 46662e2
Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.
The text was updated successfully, but these errors were encountered: