From: Fritz Reese Date: Sat, 11 Nov 2017 00:47:53 +0000 (+0000) Subject: re PR fortran/82886 (ICE with -finit-derived in gfc_conv_expr, at fortran/trans-expr... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1305135257484958d6c75e6d4a05a3de2541f287;p=gcc.git re PR fortran/82886 (ICE with -finit-derived in gfc_conv_expr, at fortran/trans-expr.c:7807) 2017-11-10 Fritz Reese PR fortran/82886 gcc/fortran/ChangeLog: PR fortran/82886 * gfortran.h (gfc_build_init_expr): New prototype. * invoke.texi (finit-derived): Update documentation. * expr.c (gfc_build_init_expr): New, from gfc_build_default_init_expr. (gfc_build_default_init_expr): Redirect to gfc_build_init_expr(,,false) (component_initializer): Force building initializers using gfc_build_init_expr(,,true). gcc/testsuite/ChangeLog: PR fortran/82886 * gfortran.dg/init_flag_16.f03: New testcase. From-SVN: r254648 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6578f7d4197..1e4348db255 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2017-11-10 Fritz Reese + + PR fortran/82886 + * gfortran.h (gfc_build_init_expr): New prototype. + * invoke.texi (finit-derived): Update documentation. + * expr.c (gfc_build_init_expr): New, from gfc_build_default_init_expr. + (gfc_build_default_init_expr): Redirect to gfc_build_init_expr(,,false) + (component_initializer): Force building initializers using + gfc_build_init_expr(,,true). + 2017-11-10 Martin Sebor PR c/81117 diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index bc05db2fbae..09abacf83ec 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4013,13 +4013,22 @@ gfc_check_assign_symbol (gfc_symbol *sym, gfc_component *comp, gfc_expr *rvalue) return true; } +/* Invoke gfc_build_init_expr to create an initializer expression, but do not + * require that an expression be built. */ + +gfc_expr * +gfc_build_default_init_expr (gfc_typespec *ts, locus *where) +{ + return gfc_build_init_expr (ts, where, false); +} /* Build an initializer for a local integer, real, complex, logical, or character variable, based on the command line flags finit-local-zero, - finit-integer=, finit-real=, finit-logical=, and finit-character=. */ + finit-integer=, finit-real=, finit-logical=, and finit-character=. + With force, an initializer is ALWAYS generated. */ gfc_expr * -gfc_build_default_init_expr (gfc_typespec *ts, locus *where) +gfc_build_init_expr (gfc_typespec *ts, locus *where, bool force) { int char_len; gfc_expr *init_expr; @@ -4028,13 +4037,24 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) /* Try to build an initializer expression. */ init_expr = gfc_get_constant_expr (ts->type, ts->kind, where); + /* If we want to force generation, make sure we default to zero. */ + gfc_init_local_real init_real = flag_init_real; + int init_logical = gfc_option.flag_init_logical; + if (force) + { + if (init_real == GFC_INIT_REAL_OFF) + init_real = GFC_INIT_REAL_ZERO; + if (init_logical == GFC_INIT_LOGICAL_OFF) + init_logical = GFC_INIT_LOGICAL_FALSE; + } + /* We will only initialize integers, reals, complex, logicals, and characters, and only if the corresponding command-line flags were set. Otherwise, we free init_expr and return null. */ switch (ts->type) { case BT_INTEGER: - if (gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF) + if (force || gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF) mpz_set_si (init_expr->value.integer, gfc_option.flag_init_integer_value); else @@ -4045,7 +4065,7 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) break; case BT_REAL: - switch (flag_init_real) + switch (init_real) { case GFC_INIT_REAL_SNAN: init_expr->is_snan = 1; @@ -4074,7 +4094,7 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) break; case BT_COMPLEX: - switch (flag_init_real) + switch (init_real) { case GFC_INIT_REAL_SNAN: init_expr->is_snan = 1; @@ -4106,9 +4126,9 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) break; case BT_LOGICAL: - if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_FALSE) + if (init_logical == GFC_INIT_LOGICAL_FALSE) init_expr->value.logical = 0; - else if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_TRUE) + else if (init_logical == GFC_INIT_LOGICAL_TRUE) init_expr->value.logical = 1; else { @@ -4120,7 +4140,7 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) case BT_CHARACTER: /* For characters, the length must be constant in order to create a default initializer. */ - if (gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON + if ((force || gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON) && ts->u.cl->length && ts->u.cl->length->expr_type == EXPR_CONSTANT) { @@ -4136,7 +4156,8 @@ gfc_build_default_init_expr (gfc_typespec *ts, locus *where) gfc_free_expr (init_expr); init_expr = NULL; } - if (!init_expr && gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON + if (!init_expr + && (force || gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON) && ts->u.cl->length && flag_max_stack_var_size != 0) { gfc_actual_arglist *arg; @@ -4391,7 +4412,8 @@ component_initializer (gfc_typespec *ts, gfc_component *c, bool generate) /* Treat simple components like locals. */ else { - init = gfc_build_default_init_expr (&c->ts, &c->loc); + /* We MUST give an initializer, so force generation. */ + init = gfc_build_init_expr (&c->ts, &c->loc, true); gfc_apply_init (&c->ts, &c->attr, init); } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 213c5da56f7..a57676a2be1 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3174,6 +3174,7 @@ bool gfc_check_pointer_assign (gfc_expr *, gfc_expr *); bool gfc_check_assign_symbol (gfc_symbol *, gfc_component *, gfc_expr *); gfc_expr *gfc_build_default_init_expr (gfc_typespec *, locus *); +gfc_expr *gfc_build_init_expr (gfc_typespec *, locus *, bool); void gfc_apply_init (gfc_typespec *, symbol_attribute *, gfc_expr *); bool gfc_has_default_initializer (gfc_symbol *); gfc_expr *gfc_default_initializer (gfc_typespec *); diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index bcb62434931..f3a8b34a26b 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -1714,9 +1714,14 @@ initialization options are provided by the the real and imaginary parts of local @code{COMPLEX} variables), @option{-finit-logical=@var{}}, and @option{-finit-character=@var{n}} (where @var{n} is an ASCII character -value) options. Components of derived type variables will be initialized -according to these flags only with @option{-finit-derived}. These options do -not initialize +value) options. + +With @option{-finit-derived}, components of derived type variables will be +initialized according to these flags. Components whose type is not covered by +an explicit @option{-finit-*} flag will be treated as described above with +@option{-finit-local-zero}. + +These options do not initialize @itemize @bullet @item objects with the POINTER attribute diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2741168bfd9..d3e15cf7a00 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-11-10 Fritz Reese + + PR fortran/82886 + * gfortran.dg/init_flag_16.f03: New testcase. + 2017-11-10 Michael Meissner * gcc.target/powerpc/p9-xxbr-3.c: New test. diff --git a/gcc/testsuite/gfortran.dg/init_flag_16.f03 b/gcc/testsuite/gfortran.dg/init_flag_16.f03 new file mode 100644 index 00000000000..a39df63d772 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/init_flag_16.f03 @@ -0,0 +1,25 @@ +! { dg-do compile } +! { dg-options "-finit-derived" } +! +! PR fortran/82886 +! +! Test a regression which caused an ICE when -finit-derived was given without +! other -finit-* flags, especially for derived-type components with potentially +! hidden basic integer components. +! + +program pr82886 + + use, intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr + type t + type(c_ptr) :: my_c_ptr + end type + +contains + + subroutine sub0() bind(c) + type(t), target :: my_f90_type + my_f90_type%my_c_ptr = c_null_ptr + end subroutine + +end