Menu ▾ ▴

#4099 Array return type causes an internal compiler error instead of a diagnostic

pending-fixed
None
Front-end
5
5 days ago
2026-09-28
No

1: Sample code that reproduces the problem.

int returns_array(void)[3] /* ERROR */
{
}

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

./bin/sdcc -c bug.c

3: SDCC version tested

Git f68fca8a4368ece9fe93b21f2e0341282b104359, SDCC 4.6.3 #0 (Linux).

Affected in valdiag testing on mcs51, mcs51-large, mcs51-stack-auto, ds390, z80, z180, r2k, r4k, sm83, tlcs90, hc08, s08, mos6502, huc6280, stm8, f8, pdk13, pdk14, and pdk15.

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

SDCC emits no source diagnostic and instead reports:

Internal error: validateLink failed in DCL_PTR_CONST(type) @ SDCCsymt.c:5541: expected DECLARATOR, got null-link

N3886 6.9.2p3 says that a function shall not have a return type that is an array type. According to the ISO C standard, all constraint violations must be diagnosed. An internal compiler error is not an acceptable substitute for a diagnostic identifying the source constraint violation.

Clang 18.1.3, GCC 13.3.0, and TCC 0.9.28rc (mob 9db1105, 2026-09-26) all diagnose the invalid declaration without an internal compiler error.

Discussion

  • Christopher Bazley

    Attaching a candidate patch to fix this bug.

    This is one of eight independent patches against SDCC commit
    c8cee3a5b4656a3d7ef97ef6078c38a016a02cfb (2026-09-28).
    The patches were also applied together to the baseline commit and built with the PIC14 and PIC16 ports disabled. The full device library build completed successfully. Focused valdiag testing of the eight new files passed on all 19 valdiag targets: 27 checks per target, zero failures.

    make -C support/regression -j2 test-ucz80:

    0 failures, 36745 tests, 6409 test cases
    
     
  • Philipp Klaus Krause

    Background: years ago, SDCC did not support returning of struct/union. For historic reasons, in SDCC source, struct/union is sometimes referred to as "aggregate", despite the C standard using that term for struct/array.
    Anyway, over time, most SDCC ports got struct/union return support. AFAIK, there are just five exceptions: the unmaintained pic14 and pic16 ports, ds390, hc08, s08 (the latter two have partial support AFAIR allowing returning struct / union up to sizeof(long long) or so). We might get full struct / union return support for ds390, hc08, s08 before SDCC 4.7.0 (AFAIK @janet-chien is looking into it).
    Once we have that, it makes indeed sense to reuse the old E_FUNC_AGGR enum for the error message for this issue, probably renaming it then to something like A_ARRAY_RETURN or so.
    I guess until then just using E_FUNC_AGGR like this patch does is okay, even if the error message is slightly misleading. It is definitely an improvement over the current situation, so I intend to apply this patch, unless some other issue comes up today.

    On the other hand, we might want to also emit an error on array return type for declarations that are not definitions (N3886 6.7.7.4p1 ).

     
    • Christopher Bazley

      Please find a new candidate fix attached. The check has moved from checkFunction to processFunc so that declarations without definitions are also diagnosed, as required by N3886 6.7.7.4p1.

      The implementation handles unnamed function types, for which func can be null. After issuing E_FUNC_AGGR, it replaces the invalid return type with int so that subsequent processing can continue.

      Function types in type names are now processed too. Testing these cases exposed another problem: an array suffix could overwrite intervening declarators in an abstract declarator's type chain. The parser now appends the array declarator to the end of that chain.

      The tests now cover both declarations and definitions of functions returning arrays, as well as valid functions returning pointers to arrays. They also cover type names with no associated symbol, including arrays of specified and unknown bounds, and corresponding valid pointer return types.

      The patch was built and tested independently against SDCC commit a1ab477f6. All eight cases passed on all 18 valdiag targets available at that baseline. The full mcs51 valdiag suite reported 0 failures, 649 tests and 371 test cases. It's probably worth running the full ucz80 regression suite too. I'll do that and report here when it completes.

      The added call to processFuncPtr in type_name is also included in the latest version of the candidate patch for [#4097]. That change only needs to be applied once.

       

      Related

      Bugs: #4097


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

        It's probably worth running the full ucz80 regression suite too. I'll do that and report here when it completes.

        Summary for 'ucz80': 0 failures, 36740 tests, 6407 test cases, 7348919 bytes, 1613716860 ticks

         
        • Philipp Klaus Krause

          Running all those regression tests can take quite some time. However, even when not running everything, I'd recommend to at least:

          • Add test-stm8-large: the stm8 port is the most modern, with many fancy features. Also the large variant uses function pointers that are wider than void *, so that case would be covered.
          • Add test-ucr3ka (or another Rabbit port, instead of or in addition to test-ucz80): The Rabbit ports are part of the z80 port family, so you get some coverage for that large port family, but you'll also have a port where the __far intrinsic named address space is not a subspace of the generic address space.
          • Add test-ds390: the ds390 port is the least modern one among the maintained ports, and still lacks many features available in other ports.
          • Add test-pdk14: pdk14 devices are very small, so including this has a good chance of catching memory-size and code size regressions.
           
  • Philipp Klaus Krause

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

    Thanks. Fixed via your patch in [r16945].

     

    Related

    Commit: [r16945]

    • Christopher Bazley

      FWIW I agree that reusing the error code was misleading. here's a followup fix.

       
      • Philipp Klaus Krause

        I'd wait on this for one month: if we get struct return support for ds390 before the trunk freeze for the SDCC 4.7.0 release, I'd just reuse the old enum value for E_FUNC_AGGR for the new E_FUNC_RETURN_ARRAY.

         
        • Philipp Klaus Krause

           

          Related

          Patches: #519

  • Philipp Klaus Krause

    • status: closed-fixed --> pending-fixed
     

Log in to post a comment.