https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84065
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P4 CC| |jakub at gcc dot gnu.org Target Milestone|--- |8.0 --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I guess the testcase kind of assumes both 32-bit target and 32-bit host, because on 64-bit host, 32-bit target we do: 1760 HOST_WIDE_INT len = gfc_mpz_get_hwi (sym->ts.u.cl->length->value.integer); 1761 1762 if (init->expr_type == EXPR_CONSTANT) 1763 gfc_set_constant_character_len (len, init, -1); and len is 0x100000004, i.e. larger than can fit into target's address space. Which in the end means allocation of 0x100000004 * 4 bytes of memory, setting that all to ' ' etc., and doing it for a bunch of similar strings. Conceptually, it would be nice if the FE could represent more efficiently these cases where there is just small amount of real data followed by a huge repetition of something (in this case ' '). Or, for this testcase, we could perhaps repeat the comparison that resolve_charlen will do, and either don't create the initializer in that case, or error right away. The former is in: --- decl.c.jj8 2018-01-23 21:35:04.000000000 +0100 +++ 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); + } } } }