re PR middle-end/60226 (ICE initializing array of elements with too large alignment)
authorMarek Polacek <polacek@redhat.com>
Tue, 8 Jul 2014 05:38:12 +0000 (05:38 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Tue, 8 Jul 2014 05:38:12 +0000 (05:38 +0000)
PR c/60226
* fold-const.c (round_up_loc): Change the parameter type.
Remove assert.
* fold-const.h (round_up_loc): Adjust declaration.
* stor-layout.c (finalize_record_size): Check for too large types.

* c-c++-common/pr60226.c: New test.

From-SVN: r212346

gcc/ChangeLog
gcc/fold-const.c
gcc/fold-const.h
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr60226.c [new file with mode: 0644]

index 1e06ded..edf3dc1 100644 (file)
@@ -1,3 +1,11 @@
+2014-07-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c/60226
+       * fold-const.c (round_up_loc): Change the parameter type.
+       Remove assert.
+       * fold-const.h (round_up_loc): Adjust declaration.
+       * stor-layout.c (finalize_record_size): Check for too large types.
+
 2014-07-07  Jan Hubicka  <hubicka@ucw.cz>
 
        * symtab.c: Include calls.h
index d22eac1..c57ac7b 100644 (file)
@@ -16647,11 +16647,10 @@ fold_ignored_result (tree t)
 /* Return the value of VALUE, rounded up to a multiple of DIVISOR. */
 
 tree
-round_up_loc (location_t loc, tree value, int divisor)
+round_up_loc (location_t loc, tree value, unsigned int divisor)
 {
   tree div = NULL_TREE;
 
-  gcc_assert (divisor > 0);
   if (divisor == 1)
     return value;
 
index dcb97a1..3b5fd84 100644 (file)
@@ -144,7 +144,7 @@ extern tree combine_comparisons (location_t, enum tree_code, enum tree_code,
 extern void debug_fold_checksum (const_tree);
 extern bool may_negate_without_overflow_p (const_tree);
 #define round_up(T,N) round_up_loc (UNKNOWN_LOCATION, T, N)
-extern tree round_up_loc (location_t, tree, int);
+extern tree round_up_loc (location_t, tree, unsigned int);
 #define round_down(T,N) round_down_loc (UNKNOWN_LOCATION, T, N)
 extern tree round_down_loc (location_t, tree, int);
 extern tree size_int_kind (HOST_WIDE_INT, enum size_type_kind);
index cfd436f..19e7adb 100644 (file)
@@ -1587,6 +1587,11 @@ finalize_record_size (record_layout_info rli)
     unpadded_size_unit
       = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
 
+  if (TREE_CODE (unpadded_size_unit) == INTEGER_CST
+      && !TREE_OVERFLOW (unpadded_size_unit)
+      && !valid_constant_size_p (unpadded_size_unit))
+    error ("type %qT is too large", rli->t);
+
   /* Round the size up to be a multiple of the required alignment.  */
   TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
   TYPE_SIZE_UNIT (rli->t)
index 2b5e354..9940e72 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c/60226
+       * c-c++-common/pr60226.c: New test.
+
 2014-07-07  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/61459
diff --git a/gcc/testsuite/c-c++-common/pr60226.c b/gcc/testsuite/c-c++-common/pr60226.c
new file mode 100644 (file)
index 0000000..3a1c261
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR c/60226 */
+/* { dg-do compile } */
+/* { dg-options "-Wno-c++-compat" { target c } } */
+
+typedef int __attribute__ ((aligned (1 << 28))) int28;
+int28 foo[4] = {}; /* { dg-error "alignment of array elements is greater than element size" } */
+typedef int __attribute__ ((aligned (1 << 29))) int29; /* { dg-error "requested alignment is too large" } */
+
+void
+f (void)
+{
+  struct { __attribute__((aligned (1 << 28))) double a; } x1;
+  struct { __attribute__((aligned (1 << 29))) double a; } x2; /* { dg-error "requested alignment is too large" } */
+}