Menu

#4005 Array to pointer conversion does not remove the _Optional qualifier from the element type

open
nobody
None
other
5
3 days ago
2026-06-06
No

1: Sample code that reproduces the problem.

void foo(_Optional const char (*paocc)[64])
{
  static_assert(_Generic(*paocc,
                         const char *: 1,
                         default: 0));
}

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

sdcc --stack-auto --std=c23 -c decay.c

3: SDCC version tested (type "sdcc -v" to find it)

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/f8/f8l TD- 4.5.24 #16456 (Mac OS X ppc)
published under GNU General Public License (GPL)

4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behavior.

Incorrect output:

decay.c:5: warning 246: static assertion failed

The code above is a minimised version of one of the examples in the 'Conversion' section of the _Optional technical specification, which also gives the following rule:

If an expression that has type array of type'' is implicitly converted to an expression with typepointer to type'' that points to the initial element of the array object, any _Optional qualifier that would otherwise have applied to the referenced type of the resultant pointer type is removed.

In this example, array-to-pointer conversion should remove the _Optional qualifier but not the const qualifier from the referenced type of the resultant pointer type.

Discussion

  • Christopher Bazley

    The issue also manifests when the array whose type decays to a pointer is a member of a struct:

    struct SAC {
      char m[64];
    };
    
    void str_from_struct(_Optional const struct SAC *pocs)
    {
      static_assert(_Generic(pocs->m,
                             const char *: 1,
                             default: 0)); // FAIL: static assertion failed
    }
    
     
  • Christopher Bazley

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

    During development of the regression tests for this issue, I found what appears to be an unrelated bug, which I have reported as https://sourceforge.net/p/sdcc/bugs/4071/
    I suggest that 4071 should be fixed separately from 4005.

    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, 641 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'mcs51-large': 0 failures, 639 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'mcs51-stack-auto': 0 failures, 640 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'ds390': 0 failures, 627 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'z80': 0 failures, 630 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'z180': 0 failures, 629 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'r2k': 0 failures, 629 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'r4k': 0 failures, 629 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'sm83': 0 failures, 629 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'tlcs90': 0 failures, 629 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'hc08': 0 failures, 628 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 's08': 0 failures, 628 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'mos6502': 0 failures, 628 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'stm8': 0 failures, 631 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'f8': 0 failures, 627 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'pdk13': 0 failures, 630 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'pdk14': 0 failures, 628 tests, 363 test cases, 0 bytes, 0 ticks
    Summary for 'pdk15': 0 failures, 626 tests, 363 test cases, 0 bytes, 0 ticks

     
  • Christopher Bazley

    I am attaching a version of this candidate bug fix that has been rebased on the revised patch for bug #4004, upon which it depends. It introduces a common array-to-pointer conversion helper. The candidate fix for bug #4004 on which this fix for bug #4005 is based has not been redesigned; its existing post-conversion type calculation simply delegates to the new helper function. Parameter type adjustment remains separate because its semantics differ: the _Optional qualifier is not removed in that case.

    The revised patch adds regression tests for this specific bug (using _Generic) and enables the existing valdiag tests str_from_structand str_from_array(albeit conditionally in the latter case, pending a fix for bug #4071).

    Tests pass for this revised version. Test commands:

    make -C device/lib clean
    make -C device/lib -j2
    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
    

    regression test results:

    Summary for 'ucz80': 0 failures, 36746 tests, 6409 test cases, 7349992 bytes, 1609699665 ticks
    

    valdiag test results:

    Summary for 'mcs51': 0 failures, 659 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'mcs51-large': 0 failures, 657 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'mcs51-stack-auto': 0 failures, 658 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'ds390': 0 failures, 645 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'z80': 0 failures, 648 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'z180': 0 failures, 647 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'r2k': 0 failures, 647 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'r4k': 0 failures, 647 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'sm83': 0 failures, 647 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'tlcs90': 0 failures, 647 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'hc08': 0 failures, 646 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 's08': 0 failures, 646 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'mos6502': 0 failures, 646 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'stm8': 0 failures, 649 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'f8': 0 failures, 645 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'pdk13': 0 failures, 648 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'pdk14': 0 failures, 646 tests, 369 test cases, 0 bytes, 0 ticks
    
    Summary for 'pdk15': 0 failures, 644 tests, 369 test cases, 0 bytes, 0 ticks
    
     

    Last edit: Christopher Bazley 3 days ago

Log in to post a comment.