aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMark Eggleston <markeggleston@gcc.gnu.org>2020-03-23 14:42:20 +0000
committerMark Eggleston <markeggleston@gcc.gnu.org>2020-03-23 14:42:20 +0000
commitb0d84ecc55f3ea86764b119040c5ffde36cd0524 (patch)
tree73d9ff77b120458df6091a1c83710812d515c6ce /gcc/fortran
parent4897bb0045dd68474176be9aafb4d77bac4b363a (diff)
downloadgcc-b0d84ecc55f3ea86764b119040c5ffde36cd0524.zip
gcc-b0d84ecc55f3ea86764b119040c5ffde36cd0524.tar.gz
gcc-b0d84ecc55f3ea86764b119040c5ffde36cd0524.tar.bz2
fortran: ICE in gfc_match_assignment PR93600
This patch builds on the original patch by Steve Kargl that fixed the ICE and produced an "Unclassifiable statement at (1)" error. The processing of parameter variables now correctly handles zero length arrays used with %kind and %len. A side affect is that "Unclassifiable" error now says "Assignment to constant expression at (1)". It also fixes PR93365. gcc/fortran/ChangeLog: PR fortran/93600 * expr.c (simplify_parameter_variable): Check whether the ref chain contains INQUIRY_LEN or INQUIRY_KIND and set inquiry boolean. When an empty array has been identified and a new new EXPR_ARRAY expression has been created only return that expression if inquiry is not set. This allows the new expression to drop through to be simplified into a EXPR_CONSTANT representing %kind or %len. * match.c (gfc_match_assignment): If lvalue doesn't have a symtree free both lvalue and rvalue expressions and return an error. * resolv.c (gfc_resolve_ref): Ensure that code to handle INQUIRY_LEN is only performed for arrays with deferred types. gcc/testsuite/ChangeLog: PR fortran/93365 PR fortran/93600 * gfortran.dg/pr93365.f90: New test. * gfortran.dg/pr93600_1.f90: New test. * gfortran.dg/pr93600_2.f90: New test.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog17
-rw-r--r--gcc/fortran/expr.c34
-rw-r--r--gcc/fortran/match.c8
-rw-r--r--gcc/fortran/resolve.c2
4 files changed, 52 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index db79f05..0591579 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,20 @@
+2020-03-23 Mark Eggleston <mark.eggleston@codethink.com>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/93600
+ * expr.c (simplify_parameter_variable): Check whether the ref
+ chain contains INQUIRY_LEN or INQUIRY_KIND and set inquiry
+ boolean. When an empty array has been identified and a new
+ new EXPR_ARRAY expression has been created only return that
+ expression if inquiry is not set. This allows the new
+ expression to drop through to be simplified into a
+ EXPR_CONSTANT representing %kind or %len.
+ * matc.c (gfc_match_assignment): If lvalue doesn't have a
+ symtree free both lvalue and rvalue expressions and return
+ an error.
+ * resolv.c (gfc_resolve_ref): Ensure that code to handle
+ INQUIRY_LEN is only performed for arrays with deferred types.
+
2020-03-18 Jakub Jelinek <jakub@redhat.com>
* class.c (generate_finalization_wrapper): Fix up duplicated word
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 79e00b4..08b0a92 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -2057,6 +2057,18 @@ simplify_parameter_variable (gfc_expr *p, int type)
}
gfc_expression_rank (p);
+ /* Is this an inquiry? */
+ bool inquiry = false;
+ gfc_ref* ref = p->ref;
+ while (ref)
+ {
+ if (ref->type == REF_INQUIRY)
+ break;
+ ref = ref->next;
+ }
+ if (ref && ref->type == REF_INQUIRY)
+ inquiry = ref->u.i == INQUIRY_LEN || ref->u.i == INQUIRY_KIND;
+
if (gfc_is_size_zero_array (p))
{
if (p->expr_type == EXPR_ARRAY)
@@ -2069,15 +2081,22 @@ simplify_parameter_variable (gfc_expr *p, int type)
e->value.constructor = NULL;
e->shape = gfc_copy_shape (p->shape, p->rank);
e->where = p->where;
- gfc_replace_expr (p, e);
- return true;
+ /* If %kind and %len are not used then we're done, otherwise
+ drop through for simplification. */
+ if (!inquiry)
+ {
+ gfc_replace_expr (p, e);
+ return true;
+ }
}
+ else
+ {
+ e = gfc_copy_expr (p->symtree->n.sym->value);
+ if (e == NULL)
+ return false;
- e = gfc_copy_expr (p->symtree->n.sym->value);
- if (e == NULL)
- return false;
-
- e->rank = p->rank;
+ e->rank = p->rank;
+ }
if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL)
e->ts.u.cl = gfc_new_charlen (gfc_current_ns, p->ts.u.cl);
@@ -2126,7 +2145,6 @@ gfc_simplify_expr (gfc_expr *p, int type)
gfc_actual_arglist *ap;
gfc_intrinsic_sym* isym = NULL;
-
if (p == NULL)
return true;
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 753a5f1..3a0c097 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1373,6 +1373,14 @@ gfc_match_assignment (void)
return m;
}
+ if (!lvalue->symtree)
+ {
+ gfc_free_expr (lvalue);
+ gfc_free_expr (rvalue);
+ return MATCH_ERROR;
+ }
+
+
gfc_set_sym_referenced (lvalue->symtree->n.sym);
new_st.op = EXEC_ASSIGN;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 23b5a2b..2dcb261 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5314,7 +5314,7 @@ gfc_resolve_ref (gfc_expr *expr)
case REF_INQUIRY:
/* Implement requirement in note 9.7 of F2018 that the result of the
LEN inquiry be a scalar. */
- if (ref->u.i == INQUIRY_LEN && array_ref)
+ if (ref->u.i == INQUIRY_LEN && array_ref && expr->ts.deferred)
{
array_ref->u.ar.type = AR_ELEMENT;
expr->rank = 0;