https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70937
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> --- For gfortran.dg/array_constructor_type_7.f03 the difference is @@ -13,6 +13,7 @@ bitsizetype D.3466; sizetype D.3467; + typedef character(kind=1) struct character(kind=1)[1:2][1:.arr][1:2][1:.arr]; D.3462 = (bitsizetype) (sizetype) _s * 8; D.3463 = (sizetype) _s; D.3464 = (bitsizetype) (sizetype) _a1 * 8; which results in try { D.3477 = D.3458; D.3478 = D.3477 * 2; D.3479 = D.3459; ... .arr = MAX_EXPR <_9, 0>; _10 = (sizetype) .arr; _11 = (bitsizetype) _10; D.3458 = _11 * 8; and thus an uninitialized use of D.3458. Note there _is_ already a decl expr, but it looks like stmt <decl_expr 0x7ffff6a4eb60 type <array_type 0x7ffff6a4b498> side-effects arg 0 <var_decl 0x7ffff7ff6a20 arr> so it is for a VAR_DECL. It looks like the Fortran FE "gimplifes" type sizes on its own (in some cases at least). The above is built here: void gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, gfc_wrapped_block * block) { ... /* Evaluate character string length. */ if (sym->ts.type == BT_CHARACTER && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl)) { gfc_conv_string_length (sym->ts.u.cl, NULL, &init); gfc_trans_vla_type_sizes (sym, &init); /* Emit a DECL_EXPR for this variable, which will cause the gimplifier to allocate storage, and all that good stuff. */ tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl); gfc_add_expr_to_block (&init, tmp); and gfc_trans_vla_type_sizes has the interesting comment: /* Make sure all type sizes and array domains are either constant, or variable or parameter decls. This is a simplified variant of gimplify_type_sizes, but we can't use it here, as none of the variables in the expressions have been gimplified yet. As type sizes and domains for various variable length arrays contain VAR_DECLs that are only initialized at gfc_trans_deferred_vars time, without this routine gimplify_type_sizes in the middle-end could result in the type sizes being gimplified earlier than where those variables are initialized. */ void gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body) This code was added by Jakub ten years ago. I can fix the wrong-code regressions by restricting place_decl_expr to work on pointer types. But all this looks like the wrong way to fix the FE issue of missing DECL_EXPRs for some of its "anonymous" types it generates. But the above FE "gimplification" code suggests that it is wrong if the gimplifier ever sees non-gimplified type sizes. In this case the FE generated { integer(kind=8) D.3445; D.3445 = args->dim[0].stride; stride.1 = D.3445 != 0 ? D.3445 : 1; args.0 = (character(kind=1)[0:D.3448][1:_args] * restrict) args->data; ubound.0 = (args->dim[0].ubound - args->dim[0].lbound) + 1; size.3 = stride.1 * ubound.0; offset.2 = -stride.1; D.3446 = (bitsizetype) (sizetype) _args * 8; which is gimplified to _4 = (sizetype) _args; _5 = (bitsizetype) _4; D.3446 = _5 * 8; but the expression (sizetype) _args was also used in the TYPE_DECLs array type TYPE_SIZE SAVE_EXPR <((bitsizetype) _4 * (bitsizetype) (sizetype) ubound.0) * 8> which the FE "gimplification" doesn't adjust. The type we end up "gimplifying" is the one built by gfc_build_qualified_array. They are connected via TYPE_NAME (but they do not share sizes, they even use differently named decls): SAVE_EXPR <((bitsizetype) (sizetype) _args * (bitsizetype) (sizetype) ubound.0) * 8> SAVE_EXPR <((bitsizetype) (sizetype) _args * (bitsizetype) (sizetype) size.3) * 8> So the following patch also fixes this PR. Index: gcc/fortran/trans-decl.c =================================================================== --- gcc/fortran/trans-decl.c (revision 235945) +++ gcc/fortran/trans-decl.c (working copy) @@ -3818,6 +3818,9 @@ gfc_trans_vla_type_sizes (gfc_symbol *sy } gfc_trans_vla_type_sizes_1 (type, body); + if (TYPE_NAME (type) + && TREE_TYPE (TYPE_NAME (type)) != type) + gfc_trans_vla_type_sizes_1 (TREE_TYPE (TYPE_NAME (type)), body); } or the following, only making sure to get the unsharing correct. Index: gcc/fortran/trans-decl.c =================================================================== --- gcc/fortran/trans-decl.c (revision 235945) +++ gcc/fortran/trans-decl.c (working copy) @@ -3818,6 +3818,11 @@ gfc_trans_vla_type_sizes (gfc_symbol *sy } gfc_trans_vla_type_sizes_1 (type, body); + /* gfc_build_qualified_array may have built this type but left TYPE_NAME + pointing to the original type whose type sizes we need to expose to + the gimplifier unsharing. */ + if (TYPE_NAME (type)) + gfc_add_expr_to_block (body, build1 (DECL_EXPR, type, TYPE_NAME (type))); } the last one I am testing now.