[Bug c/87942] New: every int seems to be unaligned in packed structure

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug c/87942] New: every int seems to be unaligned in packed structure

asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87942

            Bug ID: 87942
           Summary: every int seems to be unaligned in packed structure
           Product: gcc
           Version: 8.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: [hidden email]
  Target Milestone: ---

testcode:

#pragma pack(1)
    typedef struct
    {
        volatile int cmd;
    } test_t;
#pragma pack(0)

test_t test;

int read32()
{
    test.cmd = 11;
    return 0;
}

host: win/linux x86_64
target: arm, STM32L471
gcc versions: 4.8.3 (ok), bugs in: 5.4.1, 6.3.0, 7.2.1, 8.2.0

---
since version gcc version>=5 there seems to be a bug if pragma pack(1) is used.
gcc thinks test.cmd is missaligned, but it isn't.

The code is ok in gcc version 4. The code with AND without pack(1) should be
identical in this example.

The inner code should be something like this:
        mov     r2, #11
        str     r2, [r3, #0]

but with pack(1):
        mov     r1, #11
        mov     r2, #0
        ldr     r3, .L3
        ldrb    r0, [r3]        @ zero_extendqisi2
        strb    r1, [r3]
        ldrb    r1, [r3, #1]    @ zero_extendqisi2
        strb    r2, [r3, #1]
        ldrb    r1, [r3, #2]    @ zero_extendqisi2
        strb    r2, [r3, #2]
        mov     r0, r2
        ldrb    r1, [r3, #3]    @ zero_extendqisi2
        strb    r2, [r3, #3]

The problem is that the variable in this case is a special function register of
the chip and have to be accessed in 32bit only. Every 8bit access to this
register crashes the system.

It would be nice, if there is a compiler switch, which leeds into an error, if
a volatile variable can't be read/write in one single access.
Reply | Threaded
Open this post in threaded view
|

[Bug c/87942] every int seems to be unaligned in packed structure

asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87942

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amonakov at gcc dot gnu.org

--- Comment #1 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
(In reply to Johannes Vetter from comment #0)
> since version gcc version>=5 there seems to be a bug if pragma pack(1) is
> used. gcc thinks test.cmd is missaligned, but it isn't.
>
> The code is ok in gcc version 4. The code with AND without pack(1) should be
> identical in this example.

No, it was a bug in version 4: since 'test' does not have an initializer, it
ends up as a common definition, which could be preempted at link time with a
normal definition with less-than-int alignment. Compiling with -fno-common
leads to desired code generation, as does providing an initializer:

test_t test = { 0 };

You can also add __attribute__((aligned(4))) on the struct type to make it
aligned (while still packed).

> It would be nice, if there is a compiler switch, which leeds into an error,
> if a volatile variable can't be read/write in one single access.

I think this makes sense.
Reply | Threaded
Open this post in threaded view
|

[Bug c/87942] every int seems to be unaligned in packed structure

asolokha at gmx dot com
In reply to this post by asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87942

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think the proper fix is to mark either the struct or the variable with an
appropriate align attribute.
Reply | Threaded
Open this post in threaded view
|

[Bug c/87942] every int seems to be unaligned in packed structure

asolokha at gmx dot com
In reply to this post by asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87942

--- Comment #3 from Johannes Vetter <[hidden email]> ---
Ok, thanks a lot.

I haven't expected that an initializer could change the alignment of a
variable. "-fno-common" does not work in my case (perhaps because the variable
already has a attribute "section").

If i set the alignment of the variable AND the exported variable in the header
file, it works fine.

My problem now: in how many other cases is the same behavior? I cannot check
every global variable/struct by hand.
Reply | Threaded
Open this post in threaded view
|

[Bug c/87942] every int seems to be unaligned in packed structure

asolokha at gmx dot com
In reply to this post by asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87942

--- Comment #4 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
(In reply to Johannes Vetter from comment #3)
> My problem now: in how many other cases is the same behavior? I cannot check
> every global variable/struct by hand.

I recommend to open a new bugreport for this aspect (diagnostics enhancement).
There's -Wpacked-not-aligned now, but it doesn't capture this specific issue.

Why was it necessary to use a packed struct for device memory at all?