Bug 84185 - missing warning when ignoring attribute aligned on a member
Summary: missing warning when ignoring attribute aligned on a member
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2018-02-02 18:23 UTC by Martin Sebor
Modified: 2019-11-21 09:24 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2018-02-02 18:23:50 UTC
As mentioned in bug 84108 comment 2, GCC warns about variable declarations that specify both attribute aligned and packed, yet it requires both attributes to reduce the alignment of a struct member and doesn't indicate that a sole aligned attribute has no such effect (i.e., doesn't reduce the member's alignment).

The limitation/requirement of the aligned attribute is documented in the manual:

  When used on a struct, or struct member, the aligned attribute can only increase the alignment; in order to decrease it, the packed attribute must be specified as well.

but because it is subtle and inconsistent with how the attribute is treated for non-members, it's easy to miss.  See also bug 82914 for another example of confusion this has lead to.

Assuming it's too risky to make the attribute behave consistently for both members and non-members, GCC could help reduce the confusion (and bugs) by issuing a warning when the attribute is specified alone on a member and known to have no effect.

$ cat t.c && gcc -S -Wall -Wextra t.c
#define ASSERT(e) _Static_assert (e, #e)

struct {
  int a __attribute__ ((aligned (2)));   // attribute ignored, missing warning
} a;

ASSERT (_Alignof (a.a) == 2);            // assertion failure

struct {
  int b __attribute__ ((packed));
} b;

ASSERT (_Alignof (b.b) == 1);            // passes

struct {
  int c __attribute__ ((aligned (2), packed));
} c;

ASSERT (_Alignof (c.c) == 2);            // passes
t.c:1:19: error: static assertion failed: "_Alignof (a.a) == 2"
 #define ASSERT(e) _Static_assert (e, #e)
                   ^~~~~~~~~~~~~~
t.c:7:1: note: in expansion of macro ‘ASSERT’
 ASSERT (_Alignof (a.a) == 2);            // assertion failure
 ^~~~~~