1: Sample code that reproduces the problem.
int f(int x)
{
constexpr int c = 3;
return x + c;
}
2: Exact command used to run SDCC on this sample code.
sdcc -mz80 --std=c23 --nostdinc -S repro.c
The failure also occurs with --std=c2y.
3: SDCC version tested.
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 #16998 (Linux)
published under GNU General Public License (GPL)
This is the unpatched Compiler Explorer build.
4: Observed and expected behaviour.
SDCC exits with status 1 and reports:
Caught signal 11: SIGSEGV
The source is valid C23. c names a constexpr object; x + c is an expression using the runtime value of x. The compiler should accept the program and produce a function returning x + 3 when that sum is representable in int. Replacing c by the literal 3, or declaring it const instead of constexpr, avoids this crash. The C23 language specification is available in
WG14 N3096.
5: Additional checks and compiler comparison.
Compiler Explorer: SDCC trunk beside GCC 16.2. Both panes contain the minimal example above. SDCC uses -mz80 --std=c23; GCC uses -std=c23 -pedantic-errors -fsyntax-only. SDCC r16998 catches SIGSEGV; GCC 16.2.0 accepts the program without diagnostics.
A local test matrix contains 32 valid programs on nine configurations in both C23 and C2Y. Nineteen programs crash in every configuration/mode combination (342 failures). Configurations tested: Z80, STM8 default/large, MCS51 default/large/stack-auto, PDK14, S08 and Rabbit R2K.
Affected examples include addition, subtraction, multiplication, division, remainder, bitwise operations, a variable shift count, conditional and comma expressions, nesting, a computed array index, and local/global constexpr objects of int or long type.
Implementation observation: an expression's type can inherit the internal constexpr marker from an operand. propagateConstExpr and constExprValue then treat the computed expression as a symbol and attempt to read its initialiser through AST_SYMBOL. A captured and decoded backtrace reaches that access in constExprValue. The candidate checks the node kind before looking up or propagating a constexpr object's value.
This is separate from [bugs:#4118], whose source has an invalid constexpr parameter and crashes after error 198. It is also separate from [bugs:#3837], which concerns compound literals in constant-expression contexts.
Diff:
Related
Bugs: #3837
Bugs: #4118
Please review the attached patch created in negotiation with Codex.
The proposed testing might look excessive for the reported bug, but I can only assume that operations involving constexpr operands with non-constexpr operands are largely untested, otherwise this bug wouldn't exist. Fixing it seems quite high priority to me.