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 <[email protected]>
* 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)