Menu ▾ ▴

#4126 Conditional expressions accept incompatible pointer result operands

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

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.

Discussion

  • Christopher Bazley

    The obvious way to fix this would be to reuse the diagnoseDissimilarPtrTargetTypes but I didn't like that because it uses printFromToType and therefore produces output in the form

    tests/bug-4126.c:7: warning 244: pointer types incompatible
    from type 'char generic* auto'
      to type 'int generic* auto'
    

    which is not appropriate for the conditional operator. Instead, I created a new function, printWithTypes, to produce output resembling the following:

    tests/bug-4126.c:15: warning 244: pointer types incompatible
    with type 'char generic* fixed'
     and type 'int generic* fixed'
    
     

Log in to post a comment.