Menu ▾ ▴

#4087 Undiagnosed constraint violation when _Alignof applied to an incomplete type

open
nobody
None
Front-end
5
9 hours ago
5 days ago
No

1: Sample code that reproduces the problem.

struct incomplete;
enum { invalid_alignment = _Alignof(struct incomplete) }; /* ERROR */

2: Exact command used to run SDCC on this sample code
./bin/sdcc -c bug.c

3: SDCC version tested

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/huc6280/f8/f8l TD- 4.6.2 #0 (macOS ARM64)

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

Use of the _Alignof operator on an incomplete type violates a constraint. According to the ISO C standard, all constraint violations must be diagnosed. Clang and GCC report the constraint violation but SDCC does not. See https://godbolt.org/z/W7YEn7Tco

Discussion

  • Christopher Bazley

    I'm attaching the relevant one of five candidate patches for bugs 4085...4089.
    See earlier bug reports for details of testing.
    My only slight misgiving is that TEST2 should perhaps be dependent on SDCC having been configured for C2Y.

     
  • Philipp Klaus Krause

    Probably not a bug an SDCC user ever encountered - I guess alignof is mostly used when compiling code originally written for GCC or clang, since AFAIK our non-free competitors don't support it; in SDCC it is just the integer constant 1 anyway.

    But yes, it is a bug. When we're touching this we might as well just go all the way, and also add a W_ALIGNOF_INCOMPLETE_ARRAY_C2Y to emit a warning for the arrays when not in c2y mode.

    Also, I noticed that this still passes without warning with the patch applied:

    int a2 = _Alignof(int[][]);
    
     
    • Christopher Bazley

      I think your example probably should be accepted because the alignment of the array only depends on the alignment of its element type (which is known). Did I miss something?

       
      • Philipp Klaus Krause

        The standard says that alignof should be applied to a complete object type or an array thereof. int[] is an incomplete type, so int[][] is an array of something that is not a complete object type, so it would be a constraint violation (GCC and clang also make it an error).

        Practically, no alignment depends on anything in SDCC. Its all just 1, though AFAIK we do have open feature requests for supporting the additional values 2 and 256 for alignas.

         
        • Christopher Bazley

          Hi Philipp, please find a reworked patch attached. I hope this version does what you want. It includes tests for arrays of incomplete array type, and for complete struct types of zero size.

           
          • Philipp Klaus Krause

            That patch would still allow things like

            int a2 = _Alignof(int[][3][]);
            

            How about the attached fix instead (it passes the valdiag tests, including the one from your patch, and passes the regression tests for at least the test-ucz80 test-stm8-large test-pdk14 test-mcs51-small targets)?

             
            • Christopher Bazley

              That patch would still allow things like
              int a2 = _Alignof(int[][3][]);

              I don't think so. I added this extra test case:

              #ifdef TEST15
              #pragma std_c11
              enum { alignment = _Alignof(int[][3][]) }; /* ERROR */
              #endif
              
              ~/sdcc-git-mirror $ make -C support/valdiag -j2 | grep 'bug-4087'
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              bug-4087                            (f:  0, t:  15, c:   15, b:       0, T:         0)
              

              Start with int[][3][].
              elementType starts at type->next, skipping the outer array. It therefore points to int[3][].
              The while condition is true because this is an array and DCL_ELEM(elementType) is 3.
              The loop advances to int[].
              The loop stops because that array has an unknown bound (DCL_ELEM(elementType) == 0).
              IS_ARRAY(elementType) is still true, so E_INVALID_OP.

               

Log in to post a comment.