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)