Hi!

resolve_charlen is going to error on ilp32 target charlens above what
can fit into 32-bit signed int, but add_init_expr_to_sym is done before
resolve_charlen, allocating huge amounts of memory in those cases
when we'll error later is just waste of compile time if running on 64-bit
host with enough memory, or will unnecessarily ICE due to out of memory
otherwise.
Another option would be to emit the error resolve_charlen is going to
emit and arrange for it not to be emitted afterwards, this just seemed
to be easier.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

It would be nice if the FE had some way to express very large repetitive
EXPR_CONSTANT more efficiently, say by not allocating the memory for
the rest which is filled only by ' ', or by allowing to say this and this
is repeated after the initial portion this many times.

2018-01-26  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/84065
        * decl.c (add_init_expr_to_sym): Ignore initializers for too large
        lengths.

--- gcc/fortran/decl.c.jj       2018-01-23 21:35:04.000000000 +0100
+++ gcc/fortran/decl.c  2018-01-26 18:24:22.064763299 +0100
@@ -1757,22 +1757,32 @@ add_init_expr_to_sym (const char *name,
              if (!gfc_specification_expr (sym->ts.u.cl->length))
                return false;
 
-             HOST_WIDE_INT len = gfc_mpz_get_hwi 
(sym->ts.u.cl->length->value.integer);
-
-             if (init->expr_type == EXPR_CONSTANT)
-               gfc_set_constant_character_len (len, init, -1);
-             else if (init->expr_type == EXPR_ARRAY)
+             int k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind,
+                                        false);
+             /* resolve_charlen will complain later on if the length
+                is too large.  Just skeep the initialization in that case.  */
+             if (mpz_cmp (sym->ts.u.cl->length->value.integer,
+                          gfc_integer_kinds[k].huge) <= 0)
                {
-                 gfc_constructor *c;
+                 HOST_WIDE_INT len
+                   = gfc_mpz_get_hwi (sym->ts.u.cl->length->value.integer);
+
+                 if (init->expr_type == EXPR_CONSTANT)
+                   gfc_set_constant_character_len (len, init, -1);
+                 else if (init->expr_type == EXPR_ARRAY)
+                   {
+                     gfc_constructor *c;
 
-                 /* Build a new charlen to prevent simplification from
-                    deleting the length before it is resolved.  */
-                 init->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
-                 init->ts.u.cl->length = gfc_copy_expr (sym->ts.u.cl->length);
+                     /* Build a new charlen to prevent simplification from
+                        deleting the length before it is resolved.  */
+                     init->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
+                     init->ts.u.cl->length
+                       = gfc_copy_expr (sym->ts.u.cl->length);
 
-                 for (c = gfc_constructor_first (init->value.constructor);
-                      c; c = gfc_constructor_next (c))
-                   gfc_set_constant_character_len (len, c->expr, -1);
+                     for (c = gfc_constructor_first (init->value.constructor);
+                          c; c = gfc_constructor_next (c))
+                       gfc_set_constant_character_len (len, c->expr, -1);
+                   }
                }
            }
        }

        Jakub

Reply via email to