The error issued when the aligned attribute argument is too big
to be represented is incorrect: it says the maximum alignment
is 1U << 31 when it should actually be 1 << 28.  This was a typo
introduced when the error message was enhanced earlier in GCC 9.

The test I added to verify the fix for the typo exposed another
bug introduced in the same commit as the incorrect value in
the error message: assuming that the attribute aligned argument
fits in SHWI.

The attached patch corrects both problems.  It has been tested
on x86_64-linux.  I will commit it as obvious sometime this week
unless there are any objections or suggestions for changes.

Martin

PS I have a couple of questions related to the affected code:
1) Does GCC support building with compilers where int is not 32
   bits wide, or where BITS_PER_UNIT is not 3? (I.e., either is
   less or more?)
2) Is there a supported target that doesn't have __INT64_TYPE__?
   (And if so, how do I find it in a test?  I couldn't find
   anythhing in target-supports.exp).
PR c/89812 - incorrect maximum in error: requested alignment ‘536870912’ exceeds maximum 2147483648

gcc/c-family/ChangeLog:

	PR c/89812
	* c-common.c (check_user_alignment): Rename local.  Correct maximum
	alignment in diagnostic.  Avoid assuming argument fits in SHWI,
	convert it to UHWI when it fits.

gcc/testsuite/ChangeLog:

	PR c/89812
	* gcc.dg/attr-aligned-3.c: New test.

Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 269902)
+++ gcc/c-family/c-common.c	(working copy)
@@ -5287,9 +5287,10 @@ check_user_alignment (const_tree align, bool objfi
       return -1;
     }
 
-  int log2bitalign;
+  /* Log2 of the byte alignment ALIGN.  */
+  int log2align;
   if (tree_int_cst_sgn (align) == -1
-      || (log2bitalign = tree_log2 (align)) == -1)
+      || (log2align = tree_log2 (align)) == -1)
     {
       error ("requested alignment %qE is not a positive power of 2",
 	     align);
@@ -5299,7 +5300,7 @@ check_user_alignment (const_tree align, bool objfi
   if (objfile)
     {
       unsigned maxalign = MAX_OFILE_ALIGNMENT / BITS_PER_UNIT;
-      if (tree_to_shwi (align) > maxalign)
+      if (!tree_fits_uhwi_p (align) || tree_to_uhwi (align) > maxalign)
 	{
 	  error ("requested alignment %qE exceeds object file maximum %u",
 		 align, maxalign);
@@ -5307,14 +5308,14 @@ check_user_alignment (const_tree align, bool objfi
 	}
     }
 
-  if (log2bitalign >= HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT)
+  if (log2align >= HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT)
     {
       error ("requested alignment %qE exceeds maximum %u",
-	     align, 1U << (HOST_BITS_PER_INT - 1));
+	     align, 1U << (HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT - 1));
       return -1;
     }
 
-  return log2bitalign;
+  return log2align;
 }
 
 /* Determine the ELF symbol visibility for DECL, which is either a
Index: gcc/testsuite/gcc.dg/attr-aligned-3.c
===================================================================
--- gcc/testsuite/gcc.dg/attr-aligned-3.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/attr-aligned-3.c	(working copy)
@@ -0,0 +1,28 @@
+/* PR c/89812 - incorrect maximum in error: requested alignment '536870912'
+   exceeds maximum 2147483648
+   { dg-do compile }
+   { dg-require-effective-target size32plus } */
+
+#define POWALIGN(N) __attribute__ ((aligned ((__UINT64_TYPE__)1 << (N))))
+
+typedef POWALIGN (28) char T28;
+
+/* The maximum alignment is constrained by the number of bits in int
+   on host minus 3: HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT.  The test
+   assumes host int is 32-bits wide.  */
+typedef POWALIGN (29) char X29;  /* { dg-error "requested alignment .536870912. exceeds maximum 268435456" } */
+typedef POWALIGN (30) char X30;  /* { dg-error "requested alignment .1073741824. exceeds maximum 268435456" } */
+typedef POWALIGN (31) char X31;  /* { dg-error "requested alignment .2147483648. exceeds maximum 268435456" } */
+typedef POWALIGN (32) char X32;  /* { dg-error "requested alignment .4294967296. exceeds maximum 268435456" } */
+typedef POWALIGN (60) char X60;  /* { dg-error "requested alignment .1152921504606846976. exceeds maximum 268435456" } */
+typedef POWALIGN (63) char X63;  /* { dg-error "requested alignment .9223372036854775808. exceeds maximum 268435456" } */
+
+
+POWALIGN (28) char c28;
+
+POWALIGN (29) char c29;  /* { dg-error "requested alignment .536870912. exceeds object file maximum 268435456" } */
+POWALIGN (30) char x30;  /* { dg-error "requested alignment .1073741824. exceeds object file maximum 268435456" } */
+POWALIGN (31) char x31;  /* { dg-error "requested alignment .2147483648. exceeds object file maximum 268435456" } */
+POWALIGN (32) char x32;  /* { dg-error "requested alignment .4294967296. exceeds object file maximum 268435456" } */
+POWALIGN (60) char x60;  /* { dg-error "requested alignment .1152921504606846976. exceeds object file maximum 268435456" } */
+POWALIGN (63) char x63;  /* { dg-error "requested alignment .9223372036854775808. exceeds object file maximum 268435456" } */

Reply via email to