aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/trans-expr.c3
-rw-r--r--gcc/fortran/trans.c13
-rw-r--r--gcc/fortran/trans.h1
-rw-r--r--gcc/testsuite/gfortran.dg/deferred_character_34.f9010
4 files changed, 26 insertions, 1 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index a4e8351..2adc112 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -10796,7 +10796,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
if (expr1->ts.deferred
&& gfc_expr_attr (expr1).allocatable
&& gfc_check_dependency (expr1, expr2, true))
- rse.string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
+ rse.string_length =
+ gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
string_length = rse.string_length;
}
else
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 303abd9..8451147 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -118,6 +118,19 @@ gfc_evaluate_now (tree expr, stmtblock_t * pblock)
return gfc_evaluate_now_loc (input_location, expr, pblock);
}
+/* Like gfc_evaluate_now, but add the created variable to the
+ function scope. */
+
+tree
+gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
+{
+ tree var;
+ var = gfc_create_var_np (TREE_TYPE (expr), NULL);
+ gfc_add_decl_to_function (var);
+ gfc_add_modify (pblock, var, expr);
+
+ return var;
+}
/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
A MODIFY_EXPR is an assignment:
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 0305d33..a3726e8 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -507,6 +507,7 @@ void gfc_conv_label_variable (gfc_se * se, gfc_expr * expr);
/* If the value is not constant, Create a temporary and copy the value. */
tree gfc_evaluate_now_loc (location_t, tree, stmtblock_t *);
tree gfc_evaluate_now (tree, stmtblock_t *);
+tree gfc_evaluate_now_function_scope (tree, stmtblock_t *);
/* Find the appropriate variant of a math intrinsic. */
tree gfc_builtin_decl_for_float_kind (enum built_in_function, int);
diff --git a/gcc/testsuite/gfortran.dg/deferred_character_34.f90 b/gcc/testsuite/gfortran.dg/deferred_character_34.f90
new file mode 100644
index 0000000..2040841
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/deferred_character_34.f90
@@ -0,0 +1,10 @@
+! { dg-do run }
+! PR fortran/90561
+! This used to ICE.
+! Original test case by Gerhard Steinmetz.
+program p
+ character(:), allocatable :: z(:)
+ z = [character(2):: 'ab', 'xy']
+ z = z(2)
+ if (any(z /= 'xy')) stop 1
+end