1: Sample code that reproduces the problem.
struct S { int member; };
struct S test (int condition, struct S a, struct S b)
{
return condition ? a : b;
}
2: Exact command used to run SDCC on this sample code
sdcc --std=c23 -mz80 bug.c
3: SDCC version tested (type "sdcc -v" to find it)
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/huc6280/f8/f8l TD- 4.6.4 #16997 (Linux)
4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.
<source>:5: error 9: FATAL Compiler Internal Error in file 'gen.c' line number '6385' : code generator internal error
Contact Author with source code
Caught signal 11: SIGSEGV
Compiler returned: 1
The same translation unit is processed without diagnostics by GCC 16.2.
See https://godbolt.org/z/8E1v167rW
It also crashes SDCC when the target is stm8, but not when the target is mcs51:
https://godbolt.org/z/zbh5rqE1f
Please consider the attached candidate bug fix patch.
The conditional-expression lowering allocated an aggregate iTemp which represented an address. Later conversion of branch assignments changed the shared temporary's type into a pointer. The return generator consequently selected its scalar path and crashed. This was not a return-only problem.
The candidate allocates an automatic backing object and uses the existing structure-assignment lowering to copy only the selected operand. Returns use the object itself; member access and arguments use its address where required. Structures and unions follow the same path.
Before the fix, the original reproducer crashes Z80 and STM8; MCS51 accepts it.
After the fix, that reproducer compiles without diagnostics on Z80, STM8 default/large, MCS51 default/large/stack-auto and PDK14.
Z80 simulation passes all 54 assertions in bug-4131.c. Coverage includes one-byte and nine-byte structures, nine-byte unions, returns, assignments, member access, arguments, selected-call side effects and nested conditionals.
The complete retained valdiag fixture set was compared before and after the fix on five configurations: 4,772 diagnostic checks, with no changed results.