Menu ▾ ▴

#4145 SDCC crashes on valid expressions combining runtime and constexpr values

open
nobody
None
other
5
2 days ago
2026-10-13
No

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.

Related

Bugs: #3837
Bugs: #4118

Discussion

  • Christopher Bazley

    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -45,4 +45,4 @@
    
     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 [#4118](https://sourceforge.net/p/sdcc/bugs/4118/), whose source has an invalid `constexpr` parameter and crashes after error 198. It is also separate from [#3837](https://sourceforge.net/p/sdcc/bugs/3837/), which concerns compound literals in constant-expression contexts.
    +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.
    
     

    Related

    Bugs: #3837
    Bugs: #4118

  • Christopher Bazley

    Please review the attached patch created in negotiation with Codex.

     
  • Christopher Bazley

    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.

     

Log in to post a comment.