Bug 46354 - attribute((aligned(...))) can incorrectly decrease structure field alignment
Summary: attribute((aligned(...))) can incorrectly decrease structure field alignment
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-07 22:41 UTC by PaX Team
Modified: 2024-04-15 05:33 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.5.3, 4.8.3, 4.9.3, 5.3.0, 6.0
Last reconfirmed: 2016-01-26 00:00:00


Attachments
sample code to demonstrate structure field offsets (186 bytes, text/plain)
2010-11-07 22:43 UTC, PaX Team
Details

Note You need to log in before you can comment on or make changes to this bug.
Description PaX Team 2010-11-07 22:41:47 UTC
while investigating a clang error when compiling the linux kernel i narrowed the problem down to what seems to be a gcc bug. what happens is that despite what the gcc documentation says about the aligned attribute, gcc does decrease structure field alignment even when the packed attribute is not specified. the attached example shows that the issue is only with the attribute attached to a typedef. the relevant part of the generated asm looks like this for gcc:

        movq    xx+8(%rip), %rax
        addq    x+4(%rip), %rax   <==== bug, should be +8
        addq    p+2(%rip), %rax   <==== should it be +4?
        addq    pp+4(%rip), %rax

and for clang:

        movq    xx+8(%rip), %rax
        addq    x+8(%rip), %rax
        addq    p+2(%rip), %rax
        addq    pp+4(%rip), %rax

the tested gcc versions so far:

  gcc version 4.4.5 (Gentoo 4.4.5 p1.0, pie-0.4.5)
  gcc version 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC) 

note that fixing this bug will have a non-trivial effect on linux as this construct is relied upon throughout the compat layer (that implements transforming syscall parameters between 32 bit userland and the 64 bit kernel) so when gcc stops decreasing the natural alignment of these structure fields, all such code will have to be changed to explicitly use the packed attribute lest the kernel/userland syscall ABI break... only to run into the next issue in that the packed attribute on the structure ignores the aligned attribute in the typedef (see the +2 above), both in gcc and clang (given both compilers are affected, i'm not sure if this is a bug or feature). more interestingly, if the aligned attribute is on the structure field itself then it is properly taken into account, both in gcc and clang. so this looks like a fine mess to clean up if/when the root bug gets fixed.
Comment 1 PaX Team 2010-11-07 22:43:33 UTC
Created attachment 22314 [details]
sample code to demonstrate structure field offsets
Comment 2 Richard Biener 2010-11-07 23:00:25 UTC
Generally GCC lays out structures based on the types of the elemets, not
based on the alignment specified on fields.  Which is why I think what you
see is correct and intended.
Comment 3 PaX Team 2010-11-07 23:33:54 UTC
(In reply to comment #2)
> Generally GCC lays out structures based on the types of the elemets, not
> based on the alignment specified on fields.

according to the gcc docs, explicit alignment on structure fields *is* taken into account in that one can *increase* the natural alignment associated with a given type:

     The `aligned' attribute can only increase the alignment; but you
     can decrease it by specifying `packed' as well.  See below.

in this bug you can see that even without the packed attribute gcc can decrease the alignment. so either the docs or the implementation is buggy ;).

the second issue is that when one does use the packed attribute on a structure, the resulting field alignment seems inconsistent depending on where the aligned attribute is (typedef vs. structure field). i don't see where the docs specify or imply this behaviour.
Comment 4 Martin Sebor 2016-01-26 21:49:40 UTC
Confirmed. The documentation contradicts the implementation.  See also the duplicate bug 65672 and bug 69502.
Comment 5 Luke 2019-01-30 16:33:45 UTC
For the LLVM/Clang version of this bug, See:

https://bugs.llvm.org/show_bug.cgi?id=9253