Menu

#4073 No recommended diagnostic when calling through a pointer to an optional-qualified function

open
nobody
None
other
5
11 hours ago
7 days ago
No
  1. Sample code that reproduces the problem.
typedef void Function(void);

void implicit_dereference(_Optional Function *pof)
{
  pof();
}

void explicit_dereference(_Optional Function *pof)
{
  (*pof)();
}

void guarded_implicit_dereference(_Optional Function *pof)
{
  if (pof)
    pof();
}

void guarded_explicit_dereference(_Optional Function *pof)
{
  if (pof)
    (*pof)();
}
  1. Exact command used to run SDCC.
sdcc -c --std=c23 test.c
  1. Actual output.

No diagnostic output is produced.

  1. Expected behaviour.

An implementation that performs data-flow analysis is encouraged by the _Optional TS to diagnose dereference of a pointer to an optional-qualified type when its value cannot be proven non-null.

I therefore expected a diagnostic for both unguarded calls:

pof();
(*pof)();

The first call implicitly dereferences pof as part of applying the function-call operator; the second expresses that dereference explicitly. Neither pointer can be proven non-null.

No diagnostic is expected for either guarded call because the controlling if establishes that pof is non-null on the path containing the call.

The missing diagnostics are recommended rather than required, so their absence is not a mandatory-diagnostic conformance failure.

This case is derived from the anna example in support/valdiag/tests/_Optional-draft-2026-04-17.c, where the missing diagnostic is currently marked:

pof(); // recommended diagnostic /* IGNORE */ // BUG, should be warning!

The sample code given above deliberately avoids typeof, so this issue is independent of bugs #3916 and #3917.

  1. SDCC version.
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/huc6280/f8l TD- 4.6.2 #16838 (Linux)

Discussion

  • Christopher Bazley

    I am attaching a proposed bugfix for this issue, created with assistance from Codex. I hope that it will prove acceptable when reviewed by SDCC's maintainers.

    The main implementation question was whether to mark function calls as isSemDeref or insert extra code to diagnose them separately. The second choice is more complex but I chose it anyway. Although an explicit function call such as(*f)() could pedantically be characterised as equivalent to (&(*f))() due to the ISO C rule that the call operator only acts on function pointers, not function designators, an implicit function call such as f() cannot be characterised thus. Also, isSemDeref doesn’t seem to be used for all dereferences.

    I did the following testing of the proposed patch:

    • complete diagnostic-validation results (support/valdiag) for the default targets.
    • complete runtime regression (support/regression) results for ucz80.

    i.e.
    make -j2
    make -C support/regression clean-results
    make -C support/regression -j2 test-ucz80
    make -C support/valdiag clean
    make -C support/valdiag -j2

    Summary for 'ucz80': 0 failures, 36740 tests, 6407 test cases, 7347620 bytes, 1613638336 ticks
    Summary for 'mcs51': 0 failures, 644 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'mcs51-large': 0 failures, 642 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'mcs51-stack-auto': 0 failures, 643 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'ds390': 0 failures, 630 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'z80': 0 failures, 633 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'z180': 0 failures, 632 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'r2k': 0 failures, 632 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'r4k': 0 failures, 632 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'sm83': 0 failures, 632 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'tlcs90': 0 failures, 632 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'hc08': 0 failures, 631 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 's08': 0 failures, 631 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'mos6502': 0 failures, 631 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'stm8': 0 failures, 634 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'f8': 0 failures, 630 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'pdk13': 0 failures, 633 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'pdk14': 0 failures, 631 tests, 366 test cases, 0 bytes, 0 ticks
    Summary for 'pdk15': 0 failures, 629 tests, 366 test cases, 0 bytes, 0 ticks

     

    Last edit: Christopher Bazley 2 days ago
  • Christopher Bazley

    See above.

     
    • Philipp Klaus Krause

      The patch looks good to me.

      For now, IMO we should wait a few days for the discussion on sdcc-devel on LLM use to settle.

       

Log in to post a comment.