[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-27 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #11 from huaixin chang  ---
(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

[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-27 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #10 from huaixin chang  ---
(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

[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-27 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #7 from huaixin chang  ---
(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?

[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-27 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #6 from huaixin chang  ---
(In reply to jos...@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.

[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-27 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #5 from huaixin chang  ---
(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.

[Bug c/94338] struct member alignment is not carried over to alignment of struct variable

2020-03-26 Thread huaixin....@alibaba-inc.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338

--- Comment #1 from huaixin chang  ---
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.

[Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable

2020-03-26 Thread huaixin....@alibaba-inc.com
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@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 

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", );
printf("address of A.a %lx\n", );
printf("address of A.b %lx\n", );
printf("address of B %lx\n", );
printf("address of B.a %lx\n", );
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?