Menu ▾ ▴

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

closed-fixed
None
other
5
2026-10-07
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.

Related

Bugs: #3952
Bugs: #3954
Bugs: #4003
Bugs: #4006
Bugs: #4071
Bugs: #4162

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

     

    Related

    Bugs: #4071


    Last edit: Maarten Brock 2026-10-04
  • 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
    
     

    Related

    Bugs: #4004
    Bugs: #4071


    Last edit: Maarten Brock 2026-10-04
    • Christopher Bazley

      Please find a revised candidate fix attached, rebased on the latest candidate fix for bug [#4004].

      The array-to-pointer conversion logic and executable tests are unchanged. The code that propagated the internal volatileAccess property has been removed because it belonged to the superseded implementation of the fix for bug [#4072]. The revised patch uses the current implementation instead.

      The test comments have also been clarified. The conditional exclusion of the pointer-to-array type check remains, pending the separate fix for bug [#4071].

       

      Related

      Bugs: #4004
      Bugs: #4071
      Bugs: #4072


      Last edit: Maarten Brock 2026-10-04
      • Philipp Klaus Krause

        New functions that operate just on symbols or types, but neither AST nor iCode should be in SDCCsymt.c.

        P.S.: If SDCCsymt.c get too big we might even want to separate handling of types vs. handling of symbols in the future. SDCCsymt.c is already the second-biggest C source file in src (after SDCCast.c).

         

        Last edit: Philipp Klaus Krause 2026-10-02
        • Christopher Bazley

          Thanks, here's another attempt at a viable patch. This patch depends on the candidate fix for bug [#4004]

           

          Related

          Bugs: #4004


          Last edit: Maarten Brock 2026-10-04
  • Christopher Bazley

    Please find a reworked version of the candidate fix for this bug attached. It depends on the decay and pointer-checking code introduced by the candidate patch to fix [bugs:#3952].
    If accepted, the array-decay handling introduced by this patch will be used by a candidate patch to fix [bugs:#4006].

    Comment edited by @spth to fix the links to other bug tickets.

     

    Related

    Bugs: #3952
    Bugs: #4006


    Last edit: Philipp Klaus Krause 2026-10-07
  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    Thanks. Fixed in [r16983] via your patch.

     

    Related

    Commit: [r16983]


Log in to post a comment.