1: Sample code that reproduces the problem.
void *f(int c,int *p,char *q) { return c?p:q; }
2: Exact command used to run SDCC on this sample code.
/workspace/scratch/babc9a325375/closure-r16981/bin/sdcc -mz80 --std=c2y --nostdinc -S /workspace/scratch/babc9a325375/c2y-discovery-6/confirmed/conditional-int-char.c -o /workspace/scratch/babc9a325375/c2y-discovery-6/confirmation-results/conditional-int-char/z80/c2y/output.asm
3: SDCC version tested.
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/ds390/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15 TD- 4.6.4 #0 (Linux)
published under GNU General Public License (GPL)
Built from clean official SVN r16981 sources on Linux.
4: Observed and expected behaviour.
Every invalid example is silently accepted on all 19 C2Y configurations and Z80 C23.
WG14 N3886,
6.5.16 paragraph 3, specifies the relevant constraints.
The second and third operands are pointers to incompatible types. Neither operand is void *, a null pointer constant or nullptr. Returning the result as void * does not make the conditional expression valid. SDCC silently accepts int */char * in either order, and pointers to distinct structure types.
5: Additional checks.
Compiler Explorer: SDCC trunk and GCC 16.2 side by side.
Both panes use the sample above. SDCC uses -mz80 --std=c2y; GCC uses -std=c2y -pedantic-errors -fsyntax-only. GCC diagnoses the constraint violation; SDCC accepts it without diagnostics.
GCC 13.3.0 locally (-std=c2x) and GCC 16.2.0 through Compiler Explorer (x86-64, cg162, -std=c2y) diagnose every invalid case and accept every valid case. Both used -pedantic-errors -fsyntax-only. No Clang or TCC comparison was run.
Configurations tested: MCS51 default/large/medium/stack-auto, DS390, Z80, Z180, Rabbit 2000/4000, SM83, TLCS-90, HC08, S08, STM8 default/large, PDK13/14/15, and eZ80. These are translation checks, not runtime tests.
Implementation observation: The colon-node branch in src/SDCCast.c accepts operands when compareType succeeds in either direction, rather than applying the conditional operator's compatible-type requirement.
The obvious way to fix this would be to reuse the
diagnoseDissimilarPtrTargetTypesbut I didn't like that because it usesprintFromToTypeand therefore produces output in the formwhich is not appropriate for the conditional operator. Instead, I created a new function,
printWithTypes, to produce output resembling the following:Please consider the attached candidate bug fix patch.