]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/14179 (out of memory while parsing array with many initializers)
authorGiovanni Bajo <giovannibajo@gcc.gnu.org>
Tue, 21 Sep 2004 21:12:49 +0000 (21:12 +0000)
committerGiovanni Bajo <giovannibajo@gcc.gnu.org>
Tue, 21 Sep 2004 21:12:49 +0000 (21:12 +0000)
PR c++/14179
* decl.c (reshape_init): Extract array handling into...
(reshape_init_array): New function. Use integers instead of trees
for indices.

From-SVN: r87823

gcc/cp/ChangeLog
gcc/cp/decl.c

index e21cb0ac08ecb72db247be96312833561b7cff8c..c414de872f2f47eff39fd58becba36f7eecedddc 100644 (file)
@@ -1,3 +1,10 @@
+2004-09-21  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       PR c++/14179
+       * decl.c (reshape_init): Extract array handling into...
+       (reshape_init_array): New function. Use integers instead of trees
+       for indices.
+
 2004-09-13  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        PR c++/15857
index dfdeb1e51712f4facfaa0ab70e02e689c3d78937..c2a4a86a152d30cb5fa8e11843fbb3cfd30c1d80 100644 (file)
@@ -147,6 +147,7 @@ static int cp_missing_noreturn_ok_p PARAMS ((tree));
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
 static tree next_initializable_field (tree);
+static bool reshape_init_array (tree, tree, tree *, tree);
 static tree reshape_init (tree, tree *);
 
 /* Erroneous argument lists can use this *IFF* they do not modify it.  */
@@ -8211,6 +8212,60 @@ next_initializable_field (tree field)
   return field;
 }
 
+/* Subroutine of reshape_init. Reshape the constructor for an array. INITP
+   is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of
+   the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we
+   are building.
+   ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST
+   representing the size of the array minus one (the maximum index), or
+   NULL_TREE if the array was declared without specifying the size.  */
+
+static bool
+reshape_init_array (tree elt_type, tree max_index,
+                   tree *initp, tree new_init)
+{
+  bool sized_array_p = (max_index != NULL_TREE);
+  HOST_WIDE_INT max_index_cst = 0;
+  HOST_WIDE_INT index;
+
+  if (sized_array_p)
+    /* HWI is either 32bit or 64bit, so it must be enough to represent the
+       array size.  */
+    max_index_cst = tree_low_cst (max_index, 1);
+
+  /* Loop until there are no more initializers.  */
+  for (index = 0;
+       *initp && (!sized_array_p || index <= max_index_cst);
+       ++index)
+    {
+      tree element_init;
+      tree designated_index;
+
+      element_init = reshape_init (elt_type, initp);
+      if (element_init == error_mark_node)
+       return false;
+      TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
+      CONSTRUCTOR_ELTS (new_init) = element_init;
+      designated_index = TREE_PURPOSE (element_init);
+      if (designated_index)
+       {
+         if (TREE_CODE (designated_index) != INTEGER_CST)
+           abort ();
+         if (sized_array_p
+             && tree_int_cst_lt (max_index, designated_index))
+           {
+             error ("Designated initializer `%E' larger than array "
+                     "size", designated_index);
+             TREE_PURPOSE (element_init) = NULL_TREE;
+           }
+         else
+           index = tree_low_cst (designated_index, 1);
+       }
+    }
+
+  return true;
+}
+
 /* Undo the brace-elision allowed by [dcl.init.aggr] in a
    brace-enclosed aggregate initializer.
 
@@ -8393,21 +8448,9 @@ reshape_init (tree type, tree *initp)
             than are allowed.  */
          max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
                       ? array_type_nelts (type) : NULL_TREE);
-         /* Loop through the array elements, gathering initializers.  */
-         for (index = size_zero_node;
-              *initp && (!max_index || !tree_int_cst_lt (max_index, index));
-              index = size_binop (PLUS_EXPR, index, size_one_node))
-           {
-             tree element_init;
-
-             element_init = reshape_init (TREE_TYPE (type), initp);
-              if (element_init == error_mark_node)
-                return error_mark_node;
-             TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
-             CONSTRUCTOR_ELTS (new_init) = element_init;
-             if (TREE_PURPOSE (element_init))
-               index = convert (sizetype, TREE_PURPOSE (element_init));
-           }
+         if (!reshape_init_array (TREE_TYPE (type), max_index,
+                                  initp, new_init))
+           return error_mark_node;
        }
       else
        abort ();