Menu ▾ ▴

#4105 Unnamed pointer-to-array parameter loses its array type

closed-fixed
None
Front-end
5
2026-10-18
2026-10-02
No

Unnamed pointer-to-array parameter loses its array type

1: Sample code that reproduces the problem.

void named(int *(*p)[2]);
void unnamed(int *(*)[2]);

void show_types(int p)
{
  named(p); // constraint violation
  unnamed(p); // constraint violation
}

void test(const int *(*pc)[2])
{
  named(pc); // constraint violation
  unnamed(pc); // constraint violation
}

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

./bin/sdcc -mz80 -S bug.c

3: SDCC version tested

4.6.2 #0 (macOS ARM64) built from e2796713c3ff11ff9bac33c0f99a90711a2d6684

Affected in 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.

The two declarations specify the same parameter type: a pointer to an array of two pointers to int. Omitting the parameter name should not change that type.

The deliberately invalid calls in show_types expose the types that SDCC has constructed. On z80, SDCC prints:

bug.c:6: warning 154: converting integral to pointer without a cast
from type 'int auto'
  to type 'int generic* [2] generic* fixed'
bug.c:7: warning 154: converting integral to pointer without a cast
from type 'int auto'
  to type 'int generic* generic* fixed'

The unnamed parameter is not a pointer to array of 2 pointers, as its declaration specifies: instead, it has become a pointer to a pointer to int.

This also appears to affect qualifier diagnostics. With a candidate patch to fix bug #4004 applied, named(pc) produces warning 244, but unnamed(pc) produces no diagnostic. Both calls violate the same argument conversion constraint. The new valdiag tests that I attach to that bug report will therefore need to eschew abstract parameter declarations to ensure that the expected diagnostic messages are produced.

GCC 16.1.0, Clang 23.1.0 diagnose all four constraint violations: https://godbolt.org/z/boPhYdbvG
TCC 0.9.27 only diagnoses the first two.

Related

Bugs: #4004

Discussion

  • Christopher Bazley

    The new valdiag tests that I attach to that bug report will therefore need to eschew abstract parameter declarations to ensure that the expected diagnostic messages are produced.

    This part is an overstatement. Both the actual and the adjusted (wrong) type should provoke diagnostic messages. That needs further investigation.

     
  • Philipp Klaus Krause

    To see the types (and other data structures) in SDCC, --dump-ast, and for later stages --dump-i-code might be easier than provoking error messages.

     
  • Christopher Bazley

    Please find a candidate patch to fix this bug attached.
    From the commit message:

    The pointer direct_abstract_declarator rule overwrites an array link,
    changing int *(*)[2] into int **. Append the leading pointer chain after
    the complete direct abstract declarator to preserve the array type in
    unnamed parameters and abstract type names.
    
     
  • Christopher Bazley

    Please consider the revised patch that I am now attaching instead of the version previously attached.

    This revision removes a warning-only test that passed before the fix and did not check the type printed in the warning. The tests that expose the bug and the runtime checks for indexing, pointer arithmetic and calls are retained. The compiler fix is unchanged.

     

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

      Looks ok to me.

       
  • Christopher Bazley

    • status: open --> closed-fixed
    • assigned_to: Christopher Bazley
    • Category: other --> Front-end
     
  • Christopher Bazley

    Fixed by [r17017]

     

    Related

    Commit: [r17017]


Log in to post a comment.