Bug 65685 - Reducing alignment with alignas should be rejected
Summary: Reducing alignment with alignas should be rejected
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
: 69571 94569 94594 (view as bug list)
Depends on:
Blocks: 58601
  Show dependency treegraph
 
Reported: 2015-04-07 11:29 UTC by Jonathan Wakely
Modified: 2024-04-06 08:15 UTC (History)
4 users (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: 2015-04-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2015-04-07 11:29:25 UTC
GCC doesn't give any diagnostic for the example in 7.6.2 [dcl.align] p5:

The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers
appertaining to that entity were omitted. [ Example:
  struct alignas(8) S {};
  struct alignas(1) U {
    S s;
  };   // Error: U specifies an alignment that is less strict than
       // if the alignas(1) were omitted.
— end example ]
Comment 1 Marek Polacek 2015-04-07 17:25:19 UTC
Confirmed.
Comment 2 Martin Sebor 2016-01-23 18:09:16 UTC
Still fails with the latest trunk and always has.

Below is a slightly modified test case to compare the behavior between C++11 (using alignas), C11 (using _Alignas), and prior standards (using GCC's __attribute__ aligned).  As expected, GCC in C11 mode rejects the _Alignas specifier iB with the error below:
u.cpp:10:32: error: ‘_Alignas’ specifiers cannot reduce alignment of ‘a’

Both gcc and g++ silently accept but ignore __attribute__ aligned in B (it would be nice if they issued a warning to point that out).

Finally, as noted, g++ in C++11 mode silently accepts the code:

$ cat u.cpp && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -B/home/msebor/build/gcc-trunk-svn/gcc -S -Wall -Wextra -Wpedantic -std=c++11 -xc++ u.cpp
#if __cplusplus >= 201103L
#  define Align(N)   alignas (N)
#elif __STDC_VERSION__ >= 201112L
#  define Align(N)   _Alignas (N)
#else
#  define Align(N) __attribute__ ((aligned (N)))
#endif

typedef struct A { Align (8) char c; } A;
typedef struct B { Align (1) A a; } B;

#define A(e) typedef char Assert [1 - 2 * !(e)]

A (__alignof__ (A) == 8);
A (__alignof__ (B) == 8);
Comment 3 Martin Sebor 2016-01-24 00:31:31 UTC
Working on a patch.
Comment 4 Martin Sebor 2017-06-06 16:53:17 UTC
Not actively working on a patch anymore.
Comment 5 Jonathan Wakely 2020-07-02 08:45:35 UTC
*** Bug 94594 has been marked as a duplicate of this bug. ***
Comment 6 Jonathan Wakely 2020-07-02 08:47:50 UTC
*** Bug 94569 has been marked as a duplicate of this bug. ***
Comment 7 Jonathan Wakely 2020-07-02 13:01:06 UTC
There are two facets to this. GCC allows alignas with a weaker alignment on a type, and ignores it. GCC also allows alignas with a weaker alignment on an object declaration, and reduces the alignment. In both cases it would be conforming to issue a warning, even if the current behaviour is retained.

struct alignas(8) S {};
struct alignas(2) U {
  S s;
}; // { dg-error "alignment" }

// This assertion passes, meaning the invalid alignas(2) was silently ignored.
static_assert( alignof(U) == alignof(S), "" );

alignas(1) S s;  // { dg-error "align" }
alignas(1) U u;  // { dg-error "align" }

#ifdef __GNUC__
// These assertions pass, so GCC honours the invalid alignas(1) requests.
static_assert( alignof(s) == 1, "GCC reduced alignment of s" ); // WRONG!
static_assert( alignof(u) == 1, "GCC reduced alignment of u" ); // WRONG!
#endif
Comment 8 Andrew Pinski 2024-04-06 08:15:31 UTC
*** Bug 69571 has been marked as a duplicate of this bug. ***