On Wed, Mar 27, 2013 at 03:13:13PM +0000, Joseph S. Myers wrote:
> On Wed, 27 Mar 2013, Senthil Kumar Selvaraj wrote:
> 
> > Hi,
> > 
> > I was looking at why gcc.dg/c1x-align-3.c (test for errors, line 15) is
> > failing for the AVR target, and I found that the test expects _Alignas
> > with -__INT_MAX__ - 1 to fail with a "too large" error.
> 
> It expects either an error either about being too large, or about not 
> being a power of 2.
> 

Yes, that's right. I was focusing on the "too large" error, because
that's what is causing the test to pass for a native build
(x86_64-pc-linux).

> > Is it right to check against HOST_BITS_PER_INT, when the alignment
> 
> A check against HOST_BITS_PER_INT would be because of code inside GCC that 
> uses host "int" to store alignment values.  Ideally there wouldn't be such 
> code - ideally any alignment up to and including the size of the whole 
> target address space could be used.  (For example, alignments could always 
> be represented internally as a base-2 log.)  But given the existence of 
> such code, such a check is needed.
> 
> However, a size that is not a power of 2 (such as this one, minus a power 
> of 2) should still be detected and get an error that this test accepts, 
> whether or not that size is also too large for host int.  So look at why 
> you don't get the "requested alignment is not a power of 2" error for this 
> code with a negative alignment.
> 

The tree_log2 function, called by check_user_alignment, uses a HOST_WIDE_INT
to hold the alignment value, but masks out everything except the number of 
bits in the alignment value i.e.

        low &= ~((HOST_WIDE_INT) (-1) << prec);

where prec is 16 for the AVR target. This results in -32768 (__INT_MAX__
- 1) becoming 32768, and that is of course a power of 2. The same
behavior occurs for a native build (x86_64), except that prec is 32 in
that case.

tree_log2 appears to be a general function, so I suppose the check for
negative integers must be made in check_user_alignment. Will the
following patch work? (Bootstrapped x86_64, all alignment tests pass).

Regards
Senthil

ChangeLog

2013-03-28  Senthil Kumar Selvaraj  <senthil_kumar.selva...@atmel.com>

    * c-common.c (check_user_alignment): Emit error for negative
    constants.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index c7cdd0f..dfdfbb6 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -7308,9 +7308,10 @@ check_user_alignment (const_tree align, bool allow_zero)
     }
   else if (allow_zero && integer_zerop (align))
     return -1;
-  else if ((i = tree_log2 (align)) == -1)
+  else if (tree_int_cst_sgn (align) == -1
+           || (i = tree_log2 (align)) == -1)
     {
-      error ("requested alignment is not a power of 2");
+      error ("requested alignment is not a positive power of 2");
       return -1;
     }
   else if (i >= HOST_BITS_PER_INT - BITS_PER_UNIT_LOG)

Reply via email to