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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|accepts-invalid             |rejects-valid
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-02-20
                 CC|                            |msebor at gcc dot gnu.org
     Ever confirmed|0                           |1
      Known to fail|                            |8.2.0, 9.0

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
Confirmed.

The reason why the __attribute__ is accepted is because it's not considered a
C++ 11 form of specifying alignment and so it's subject to less checking (done
by the check_cxx_fundamental_alignment_constraints function).

The alignas form is considered a C++ form (has ATTR_FLAG_CXX11 bit set in flags
below) and so makes it pass the first test. The cxx_fundamental_alignment_p()
test also fails (the fundamental alignment on aarch64 is 16).  The third if
statement is entered, followed by the else block of the inner if.  There,
MAX_STACK_ALIGNMENT is used as the upper bound.  On aarch64,
MAX_STACK_ALIGNMENT is defined to STACK_BOUNDARY which is 16, and that is why
alignas(128) is considered invalid.  In contrast, on x86_64,
MAX_STACK_ALIGNMENT is defined to MAX_OFILE_ALIGNMENT, both of which are
2147483648.

So either MAX_STACK_ALIGNMENT on aarch64 is wrong or the test in
check_cxx_fundamental_alignment_constraint is wrong.

MAX_STACK_ALIGNMENT is defined in section 18.5 Storage Layout of the internals
manual as:

  Biggest stack alignment guaranteed by the backend. Use this macro to specify
the maximum alignment of a variable on stack.

and with the following (far more descriptive) comment in gcc/defaults.h:

/* MAX_STACK_ALIGNMENT is the maximum stack alignment guaranteed by
   the backend.  MAX_SUPPORTED_STACK_ALIGNMENT is the maximum best
   effort stack alignment supported by the backend.  If the backend
   supports stack alignment, MAX_SUPPORTED_STACK_ALIGNMENT and
   MAX_STACK_ALIGNMENT are the same.  Otherwise, the incoming stack
   boundary will limit the maximum guaranteed stack alignment.  */

It's a little ambiguous but my guess is that MAX_STACK_ALIGNMENT is meant to be
the maximum alignment the back-end will maintain for the stack pointer in
general, independent of any overaligned variables, and isn't intended as
constraint on the alignment of explicitly overaligned stack variables.  (I can
think of no reason why the back-end would impose any such constraint on the
stack.)  If that's correct the test for MAX_STACK_ALIGNMENT is the bug.  The
test was introduced with the implementation of the alignas specifier in
r192199.

check_cxx_fundamental_alignment_constraints (tree node,
                                             unsigned align_log,
                                             int flags)
{
  bool alignment_too_large_p = false;
  unsigned requested_alignment = (1U << align_log) * BITS_PER_UNIT;
  unsigned max_align = 0;

  if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat)
      || (node == NULL_TREE || node == error_mark_node))
    return true;

  if (cxx_fundamental_alignment_p (requested_alignment))
    return true;

  if (VAR_P (node))
    {
      if (TREE_STATIC (node) || DECL_EXTERNAL (node))
        /* For file scope variables and static members, the target supports
           alignments that are at most MAX_OFILE_ALIGNMENT.  */
        max_align = MAX_OFILE_ALIGNMENT;
      else
        /* For stack variables, the target supports at most
           MAX_STACK_ALIGNMENT.  */
        max_align = MAX_STACK_ALIGNMENT;
      if (requested_alignment > max_align)
        alignment_too_large_p = true;
    }

Reply via email to