Menu ▾ ▴

#4230 constexpr boolean initialisers that change value go undiagnosed

open
nobody
None
Front-end
5
3 days ago
3 days ago
No

1: Sample code that reproduces the problem.

constexpr _Bool object = 2;

2: Exact command used to run SDCC on this sample code.

sdcc -mz80 --std=c2y --nostdinc -S bug.c -o bug.asm

3: SDCC version tested.

Official SDCC 4.6.4 #17081 Linux snapshot, with native sdcpp 13.5.0, tested 25 October 2026.

4: Observed and expected behaviour.

SDCC returns status 0 and emits no diagnostic. It implicitly converts the integer value 2 to the boolean value 1.

WG14 N3886 6.7.2 paragraph 5 requires a constexpr initialiser's value to be exactly representable in its corresponding target type, without changing the value. This is in Constraints. N3886 6.3.2.2 paragraph 1 specifies the ordinary conversion to bool: nonzero arithmetic values become true. Here that conversion changes 2 to 1, violating the constexpr requirement. The integer constant expression requirement in 6.7.2 paragraph 6 is satisfied; the missing check is exact representability, not source-expression type.

A diagnostic is therefore required. This does not request an error instead of a warning: either is a diagnostic. Ordinary _Bool object = 2; remains valid, as does constexpr _Bool object = (_Bool)2;, because the explicit conversion has already produced the value 1 before constexpr initialisation.

Reference: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3886.pdf, 6.7.2p5–6 and 6.3.2.2p1.

5: Additional checks.

Six invalid forms are silently accepted: scalar 2, scalar -1, an array element with value 2, a structure member with value 2, a local constexpr boolean with value 2, and a constexpr integer named source with value 2 used to initialise a constexpr boolean. Four valid cases compile silently: values 0 and 1, explicit (_Bool)2, and ordinary non-constexpr initialisation with 2.

All ten forms were checked on Z80, MCS51, STM8, PDK14 and MOS6502 in both C23 and C2Y modes, on both the official baseline and a locally built r17081 compiler with the [bugs:#4178] fix candidate applied.

Related reports: [bugs:#4178] checks the source type of constexpr integer initialisers; its candidate does not diagnose this boolean value change. [bugs:#4191] concerns inexact conversion to floating objects; its candidate returns immediately for a boolean destination. These are distinct conversion paths.

Related

Bugs: #4178
Bugs: #4191

Discussion


Log in to post a comment.