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

--- Comment #23 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Martin Sebor from comment #22)
> The warning on the test case in comment #21 looks good to me.  Thanks! 
> 
> From reading comment #1 I'm not sure your patch does quite what you
> described there.  It doesn't warn on the declaration of the global object x
> below:
> 
> typedef unsigned long long __u64 __attribute__((aligned(4),
> warn_if_not_aligned(8)));
> 
> static char c;
> static __u64 x;
> 
> even though x is 4-byte aligned.  (It does warn when a __u64 member is
> declared in a packed struct.)

This is by design.  The current description is at:

https://gcc.gnu.org/ml/gcc-patches/2017-06/msg00180.html

__attribute__((warn_if_not_aligned(N))) issues a warning if the field
in a struct or union is not aligned to N:

typedef unsigned long long __u64
  __attribute__((aligned(4),warn_if_not_aligned(8)));

struct foo
{
  int i1;
  int i2;
  __u64 x;
};

__u64 is aligned to 4 bytes.  But inside struct foo, __u64 should be
aligned at 8 bytes.  It is used to define struct foo in such a way that
struct foo has the same layout and x has the same alignment when __u64
is aligned at either 4 or 8 bytes.

Since struct foo is normally aligned to 4 bytes, a warning will be issued:

warning: alignment 4 of ‘struct foo’ is less than 8

Align struct foo to 8 bytes:

struct foo
{
  int i1;
  int i2;
  __u64 x;
} __attribute__((aligned(8)));

silences the warning.  It also warns the field with misaligned offset:

struct foo
{
  int i1;
  int i2;
  int i3;
  __u64 x;
} __attribute__((aligned(8)));

warning: ‘x’ offset 12 in ‘struct foo’ isn't aligned to 8

The same warning is also issued without the warn_if_not_aligned attribute
for the field with explicitly specified alignment in a packed struct or
union:

struct __attribute__ ((aligned (8))) S8 { char a[8]; };
struct __attribute__ ((packed)) S {
  struct S8 s8;
};

warning: alignment 1 of ‘struct S’ is less than 8

Reply via email to