public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable
@ 2020-03-26  8:51 huaixin.chx@alibaba-inc.com
  2020-03-26  8:58 ` [Bug c/94338] " huaixin.chx@alibaba-inc.com
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-26  8:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

            Bug ID: 94338
           Summary: struct member alignment is not carried over to
                    alignment of struct variable
           Product: gcc
           Version: lto
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: huaixin.chx@alibaba-inc.com
  Target Milestone: ---

Document says that “alignment of any given struct or union type is required by
the ISO C standard to be at least a perfect multiple of the lowest common
multiple of the alignments of all of the members of the struct or union in
question.” When the alignment requirement of struct variable is smaller than
the alignment requirement of its member variable, the compiler's behavior is
not specified.

Here is the code.

--------------------------------
#include <stdio.h>

struct {
        long a __attribute__((__aligned__(128)));
        long b __attribute__((__aligned__(128)));
} A __attribute__((__aligned__(4)));

struct {
        int a;
} B;

int main()
{
        printf("address of A %lx\n", &A);
        printf("address of A.a %lx\n", &A.a);
        printf("address of A.b %lx\n", &A.b);
        printf("address of B %lx\n", &B);
        printf("address of B.a %lx\n", &B.a);
        return 0;
}
--------------------------------
And it goes like this.

$gcc align.c -o align

$./align
address of A 42003c
address of A.a 42003c
address of A.b 4200bc
address of B 420038
address of B.a 420038

--------------------------------
Member a and b of struct variable A are not aligned to 128-byte boundary. I
wonder if it is the users' responsible not to write like this. Or is it the
compiler's responsible to align A.a and A.b to 128-byte boundary?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
@ 2020-03-26  8:58 ` huaixin.chx@alibaba-inc.com
  2020-03-26  9:20 ` rguenth at gcc dot gnu.org
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-26  8:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #1 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
I have tested on x86_64 with gcc version 4.8.5 20150623,
and also arm with gcc version 9.2.1 20190812.

They behaves the same.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
  2020-03-26  8:58 ` [Bug c/94338] " huaixin.chx@alibaba-inc.com
@ 2020-03-26  9:20 ` rguenth at gcc dot gnu.org
  2020-03-26 17:50 ` joseph at codesourcery dot com
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-03-26  9:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
            Version|lto                         |9.2.1
           Keywords|                            |diagnostic

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think the testcase is ill-formed and should be diagnosed in some form.
IIRC there's some documented behavior (that's not implemented) that __aligned__
only increases alignment unless __packed__ is used.  With __packed__ the
testcase behaves as expected I think.

Note __attribute__((__aligned__(4))) applies to 'A', not its type.

Not sure if behavior changes if you use a typedef that is aligned to 4.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
  2020-03-26  8:58 ` [Bug c/94338] " huaixin.chx@alibaba-inc.com
  2020-03-26  9:20 ` rguenth at gcc dot gnu.org
@ 2020-03-26 17:50 ` joseph at codesourcery dot com
  2020-03-26 19:50 ` msebor at gcc dot gnu.org
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: joseph at codesourcery dot com @ 2020-03-26 17:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #3 from joseph at codesourcery dot com <joseph at codesourcery dot com> ---
It's a mistake to be referring to the C standard for the interpretation of 
alignment attributes.  The C standard way of specifying alignment is 
_Alignas, not __attribute__, and if you write equivalent code using 
_Alignas you get an error "error: '_Alignas' specifiers cannot reduce 
alignment of 'A'", which corresponds to the constraint "The combined 
effect of all alignment specifiers in a declaration shall not specify an 
alignment that is less strict than the alignment that would otherwise be 
required for the type of the object or member being declared.".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (2 preceding siblings ...)
  2020-03-26 17:50 ` joseph at codesourcery dot com
@ 2020-03-26 19:50 ` msebor at gcc dot gnu.org
  2020-03-27  9:51 ` huaixin.chx@alibaba-inc.com
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-03-26 19:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |msebor at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2020-03-26

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
Sounds like there's agreement that the code should at least get a warning then,
so confirmed. 

The attribute aligned section of the manual describing the variable attribute
says:

  When used on a struct, or struct member, the aligned attribute can only
increase the alignment...

It's not clear whether struct here refers to a type or a variable (I'm guessing
it's former but it's in the Common Variable Attribute section so it could
easily be read as the latter).  Either way, reducing the alignment of an object
whose members explicitly ask for stricter alignment seems like a dangerous
thing to do without a warning.

I'll see if I can do this for GCC 11.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (3 preceding siblings ...)
  2020-03-26 19:50 ` msebor at gcc dot gnu.org
@ 2020-03-27  9:51 ` huaixin.chx@alibaba-inc.com
  2020-03-27  9:57 ` huaixin.chx@alibaba-inc.com
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-27  9:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #5 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
(In reply to Richard Biener from comment #2)
> I think the testcase is ill-formed and should be diagnosed in some form.
> IIRC there's some documented behavior (that's not implemented) that
> __aligned__
> only increases alignment unless __packed__ is used.  With __packed__ the
> testcase behaves as expected I think.
> 
> Note __attribute__((__aligned__(4))) applies to 'A', not its type.
Yes, I missed this and quoted wrong document for this case.

> 
> Not sure if behavior changes if you use a typedef that is aligned to 4.

If a use a typedef that is aligned to 4 like this:

typedef struct {
        long a __attribute__((__aligned__(128)));
        long b __attribute__((__aligned__(128)));
} foo __attribute__((__aligned(4)));

foo A;

Or align variable A to 4 only like this:

typedef struct {
        long a __attribute__((__aligned__(128)));
        long b __attribute__((__aligned__(128)));
} foo;
foo A __attribute__((__aligned(4)));

I will get warned while compiling and alignment is as expected.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (4 preceding siblings ...)
  2020-03-27  9:51 ` huaixin.chx@alibaba-inc.com
@ 2020-03-27  9:57 ` huaixin.chx@alibaba-inc.com
  2020-03-27 10:17 ` huaixin.chx@alibaba-inc.com
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-27  9:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #6 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
(In reply to joseph@codesourcery.com from comment #3)
> It's a mistake to be referring to the C standard for the interpretation of 
> alignment attributes.  The C standard way of specifying alignment is 
> _Alignas, not __attribute__, and if you write equivalent code using 
> _Alignas you get an error "error: '_Alignas' specifiers cannot reduce 
> alignment of 'A'", which corresponds to the constraint "The combined 
> effect of all alignment specifiers in a declaration shall not specify an 
> alignment that is less strict than the alignment that would otherwise be 
> required for the type of the object or member being declared.".

Yes, I tested with _Alignas and got that error.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (5 preceding siblings ...)
  2020-03-27  9:57 ` huaixin.chx@alibaba-inc.com
@ 2020-03-27 10:17 ` huaixin.chx@alibaba-inc.com
  2020-03-27 10:32 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-27 10:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #7 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
(In reply to Martin Sebor from comment #4)
> Sounds like there's agreement that the code should at least get a warning
> then, so confirmed. 
> 
> The attribute aligned section of the manual describing the variable
> attribute says:
> 
>   When used on a struct, or struct member, the aligned attribute can only
> increase the alignment...
> 
> It's not clear whether struct here refers to a type or a variable (I'm
> guessing it's former but it's in the Common Variable Attribute section so it
> could easily be read as the latter).  Either way, reducing the alignment of
> an object whose members explicitly ask for stricter alignment seems like a
> dangerous thing to do without a warning.
> 
> I'll see if I can do this for GCC 11.

It seems that the compiler thinks A.a is already aligned to 128-byte. Because
as I print alignof(A.a) and alignof(A.b) with the same definition, they are
128.

$./align
address of A 0x42003c
alignof A 4
address of A.a 0x42003c
alignof A.a 128
address of A.b 0x4200bc
alignof A.b 128

Is it in your consideration to actually align A.a to 128-byte boundary?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (6 preceding siblings ...)
  2020-03-27 10:17 ` huaixin.chx@alibaba-inc.com
@ 2020-03-27 10:32 ` rguenth at gcc dot gnu.org
  2020-03-27 10:38 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-03-27 10:32 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to huaixin chang from comment #7)
> (In reply to Martin Sebor from comment #4)
> > Sounds like there's agreement that the code should at least get a warning
> > then, so confirmed. 
> > 
> > The attribute aligned section of the manual describing the variable
> > attribute says:
> > 
> >   When used on a struct, or struct member, the aligned attribute can only
> > increase the alignment...
> > 
> > It's not clear whether struct here refers to a type or a variable (I'm
> > guessing it's former but it's in the Common Variable Attribute section so it
> > could easily be read as the latter).  Either way, reducing the alignment of
> > an object whose members explicitly ask for stricter alignment seems like a
> > dangerous thing to do without a warning.
> > 
> > I'll see if I can do this for GCC 11.
> 
> It seems that the compiler thinks A.a is already aligned to 128-byte.
> Because as I print alignof(A.a) and alignof(A.b) with the same definition,
> they are 128.
> 
> $./align
> address of A 0x42003c
> alignof A 4
> address of A.a 0x42003c
> alignof A.a 128
> address of A.b 0x4200bc
> alignof A.b 128
> 
> Is it in your consideration to actually align A.a to 128-byte boundary?

I think there are only two reasonable actions.

 a) warn but otherwise change nothing
 b) reject the case similar to _Alignof

ignoring the user specification as appearantly is done for the typedef
and decl annotation isn't something we can do because it may have ABI impacts.
That is, we need to make sure to not change layout & alignment of structures
with such embedded objects.

I'd lean towards b) here because as you show the actual behavior is
broken.

When you for example exchange 'long' with v4si typedefed as
typedef int v4si __attribute__((vector_size(16))), do you then
get aligned movaps when the actual structure is unaligned?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (7 preceding siblings ...)
  2020-03-27 10:32 ` rguenth at gcc dot gnu.org
@ 2020-03-27 10:38 ` rguenth at gcc dot gnu.org
  2020-03-27 13:36 ` huaixin.chx@alibaba-inc.com
  2020-03-27 23:36 ` huaixin.chx@alibaba-inc.com
  10 siblings, 0 replies; 12+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-03-27 10:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw,

struct X {
    long a __attribute__((__aligned__(128)));
    long b __attribute__((__aligned__(128)));
};
struct X A __attribute__((__aligned__(4)));

is not diagnosed (this is what your testcase is, decomposed).

I can't reproduce the diagnostics you describe in comment#5

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (8 preceding siblings ...)
  2020-03-27 10:38 ` rguenth at gcc dot gnu.org
@ 2020-03-27 13:36 ` huaixin.chx@alibaba-inc.com
  2020-03-27 23:36 ` huaixin.chx@alibaba-inc.com
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-27 13:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #10 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
(In reply to Richard Biener from comment #9)
> Btw,
> 
> struct X {
>     long a __attribute__((__aligned__(128)));
>     long b __attribute__((__aligned__(128)));
> };
> struct X A __attribute__((__aligned__(4)));
> 
> is not diagnosed (this is what your testcase is, decomposed).
> 
> I can't reproduce the diagnostics you describe in comment#5

I am sorry that I made a mistake in testing typedef described in comment#5.

I spelled __aligned__ into __aligned, got warned "warning: '__aligned'
attribute directive ignored [-Wattributes]", and thought I got diagnosed
because of reduction in alignment. As a result, neither type foo nor object A
is reduced in alignment with the code describe in comment#5.

I have tested typedef again, and found that it behaves the same with using
struct under gcc 9.2.1. That is to say, no matter I define A using struct like:

-----------------------------------
struct X {
    long a __attribute__((__aligned__(128)));
    long b __attribute__((__aligned__(128)));
};
struct X A __attribute__((__aligned__(4)));

or use typedef and reduce the alignment of type foo like:
-----------------------------------
typedef struct {
        long a __attribute__((__aligned__(128)));
        long b __attribute__((__aligned__(128)));
} foo __attribute__((__aligned(4)));

foo A;

or use typedef and reduce the alignment of A like:
-----------------------------------
typedef struct {
        long a __attribute__((__aligned__(128)));
        long b __attribute__((__aligned__(128)));
} foo;

foo A __attribute__((__aligned__(4)));

I got no warn on compiling and it behaves like this.
-----------------------------------
address of A 0x42003c
alignof A 4
address of A.a 0x42003c
alignof A.a 128
address of A.b 0x4200bc
alignof A.b 128
address of B 0x420038

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/94338] struct member alignment is not carried over to alignment of struct variable
  2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
                   ` (9 preceding siblings ...)
  2020-03-27 13:36 ` huaixin.chx@alibaba-inc.com
@ 2020-03-27 23:36 ` huaixin.chx@alibaba-inc.com
  10 siblings, 0 replies; 12+ messages in thread
From: huaixin.chx@alibaba-inc.com @ 2020-03-27 23:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #11 from huaixin chang <huaixin.chx@alibaba-inc.com> ---
(In reply to huaixin chang from comment #10)
> (In reply to Richard Biener from comment #9)
> > Btw,
> > 
> > struct X {
> >     long a __attribute__((__aligned__(128)));
> >     long b __attribute__((__aligned__(128)));
> > };
> > struct X A __attribute__((__aligned__(4)));
> > 
> > is not diagnosed (this is what your testcase is, decomposed).
> > 
> > I can't reproduce the diagnostics you describe in comment#5
> 
> I am sorry that I made a mistake in testing typedef described in comment#5.
> 
> I spelled __aligned__ into __aligned, got warned "warning: '__aligned'
> attribute directive ignored [-Wattributes]", and thought I got diagnosed
> because of reduction in alignment. As a result, neither type foo nor object
> A is reduced in alignment with the code describe in comment#5.
> 
> I have tested typedef again, and found that it behaves the same with using
> struct under gcc 9.2.1. That is to say, no matter I define A using struct
> like:
> 
> -----------------------------------
> struct X {
>     long a __attribute__((__aligned__(128)));
>     long b __attribute__((__aligned__(128)));
> };
> struct X A __attribute__((__aligned__(4)));
> 
> or use typedef and reduce the alignment of type foo like:
> -----------------------------------
> typedef struct {
>         long a __attribute__((__aligned__(128)));
>         long b __attribute__((__aligned__(128)));
> } foo __attribute__((__aligned(4)));

Another spelling mistake. It should be:

} foo __attribute__((__aligned__(4)));

> 
> foo A;
> 
> or use typedef and reduce the alignment of A like:
> -----------------------------------
> typedef struct {
>         long a __attribute__((__aligned__(128)));
>         long b __attribute__((__aligned__(128)));
> } foo;
> 
> foo A __attribute__((__aligned__(4)));
> 
> I got no warn on compiling and it behaves like this.
> -----------------------------------
> address of A 0x42003c
> alignof A 4
> address of A.a 0x42003c
> alignof A.a 128
> address of A.b 0x4200bc
> alignof A.b 128
> address of B 0x420038

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-03-27 23:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26  8:51 [Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable huaixin.chx@alibaba-inc.com
2020-03-26  8:58 ` [Bug c/94338] " huaixin.chx@alibaba-inc.com
2020-03-26  9:20 ` rguenth at gcc dot gnu.org
2020-03-26 17:50 ` joseph at codesourcery dot com
2020-03-26 19:50 ` msebor at gcc dot gnu.org
2020-03-27  9:51 ` huaixin.chx@alibaba-inc.com
2020-03-27  9:57 ` huaixin.chx@alibaba-inc.com
2020-03-27 10:17 ` huaixin.chx@alibaba-inc.com
2020-03-27 10:32 ` rguenth at gcc dot gnu.org
2020-03-27 10:38 ` rguenth at gcc dot gnu.org
2020-03-27 13:36 ` huaixin.chx@alibaba-inc.com
2020-03-27 23:36 ` huaixin.chx@alibaba-inc.com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).