aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorSteven G. Kargl <kargl@gcc.gnu.org>2015-10-24 16:20:26 +0000
committerSteven G. Kargl <kargl@gcc.gnu.org>2015-10-24 16:20:26 +0000
commit8d48826b99b81b7ed96c5db08ec8334a2b0c6557 (patch)
treefc9895b536072c30abae69ea95b29645078ed28c /gcc/fortran
parentae1158c42534a9becfb51585b9b69df8d0d13a10 (diff)
downloadgcc-8d48826b99b81b7ed96c5db08ec8334a2b0c6557.zip
gcc-8d48826b99b81b7ed96c5db08ec8334a2b0c6557.tar.gz
gcc-8d48826b99b81b7ed96c5db08ec8334a2b0c6557.tar.bz2
re PR fortran/67805 (ICE on array constructor with wrong character specification)
2015-10-24 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/67805 * array.c (gfc_match_array_constructor): Check for error from type spec matching. * decl.c (char_len_param_value): Check for valid of charlen parameter. Reap dead code dating to 2008. match.c (gfc_match_type_spec): Special case the keyword use in REAL. 2015-10-24 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/67805 * gfortran.dg/pr67805.f90: New testcase. * gfortran.dg/array_constructor_26.f03: Update testcase. * gfortran.dg/array_constructor_27.f03: Ditto. * gfortran.dg/char_type_len_2.f90: Ditto. * gfortran.dg/pr67802.f90: Ditto. * gfortran.dg/used_before_typed_3.f90: Ditto. From-SVN: r229287
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/array.c8
-rw-r--r--gcc/fortran/decl.c67
-rw-r--r--gcc/fortran/match.c5
4 files changed, 66 insertions, 23 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7ed2bc5..67d1fb0 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2015-10-24 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/67805
+ * array.c (gfc_match_array_constructor): Check for error from type
+ spec matching.
+ * decl.c (char_len_param_value): Check for valid of charlen parameter.
+ Reap dead code dating to 2008.
+ match.c (gfc_match_type_spec): Special case the keyword use in REAL.
+
2015-10-23 Mikhail Maltsev <maltsevm@gmail.com>
* trans-common.c (create_common): Adjust to use flag_checking.
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 276737b..2355a98 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -1080,7 +1080,8 @@ gfc_match_array_constructor (gfc_expr **result)
/* Try to match an optional "type-spec ::" */
gfc_clear_ts (&ts);
gfc_new_undo_checkpoint (changed_syms);
- if (gfc_match_type_spec (&ts) == MATCH_YES)
+ m = gfc_match_type_spec (&ts);
+ if (m == MATCH_YES)
{
seen_ts = (gfc_match (" ::") == MATCH_YES);
@@ -1102,6 +1103,11 @@ gfc_match_array_constructor (gfc_expr **result)
}
}
}
+ else if (m == MATCH_ERROR)
+ {
+ gfc_restore_last_undo_checkpoint ();
+ goto cleanup;
+ }
if (seen_ts)
gfc_drop_last_undo_checkpoint ();
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index c752677..200a128 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -715,36 +715,59 @@ char_len_param_value (gfc_expr **expr, bool *deferred)
if ((*expr)->expr_type == EXPR_FUNCTION)
{
- if ((*expr)->value.function.actual
- && (*expr)->value.function.actual->expr->symtree)
+ if ((*expr)->ts.type == BT_INTEGER
+ || ((*expr)->ts.type == BT_UNKNOWN
+ && strcmp((*expr)->symtree->name, "null") != 0))
+ return MATCH_YES;
+
+ goto syntax;
+ }
+ else if ((*expr)->expr_type == EXPR_CONSTANT)
+ {
+ /* F2008, 4.4.3.1: The length is a type parameter; its kind is
+ processor dependent and its value is greater than or equal to zero.
+ F2008, 4.4.3.2: If the character length parameter value evaluates
+ to a negative value, the length of character entities declared
+ is zero. */
+
+ if ((*expr)->ts.type == BT_INTEGER)
{
- gfc_expr *e;
- e = (*expr)->value.function.actual->expr;
- if (e->symtree->n.sym->attr.flavor == FL_PROCEDURE
- && e->expr_type == EXPR_VARIABLE)
- {
- if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
- goto syntax;
- if (e->symtree->n.sym->ts.type == BT_CHARACTER
- && e->symtree->n.sym->ts.u.cl
- && e->symtree->n.sym->ts.u.cl->length->ts.type == BT_UNKNOWN)
- goto syntax;
- }
+ if (mpz_cmp_si ((*expr)->value.integer, 0) < 0)
+ mpz_set_si ((*expr)->value.integer, 0);
}
+ else
+ goto syntax;
}
+ else if ((*expr)->expr_type == EXPR_ARRAY)
+ goto syntax;
+ else if ((*expr)->expr_type == EXPR_VARIABLE)
+ {
+ gfc_expr *e;
+
+ e = gfc_copy_expr (*expr);
+
+ /* This catches the invalid code "[character(m(2:3)) :: 'x', 'y']",
+ which causes an ICE if gfc_reduce_init_expr() is called. */
+ if (e->ref && e->ref->u.ar.type == AR_UNKNOWN
+ && e->ref->u.ar.dimen_type[0] == DIMEN_RANGE)
+ goto syntax;
+
+ gfc_reduce_init_expr (e);
+
+ if ((e->ref && e->ref->u.ar.type != AR_ELEMENT)
+ || (!e->ref && e->expr_type == EXPR_ARRAY))
+ {
+ gfc_free_expr (e);
+ goto syntax;
+ }
- /* F2008, 4.4.3.1: The length is a type parameter; its kind is processor
- dependent and its value is greater than or equal to zero.
- F2008, 4.4.3.2: If the character length parameter value evaluates to
- a negative value, the length of character entities declared is zero. */
- if ((*expr)->expr_type == EXPR_CONSTANT
- && mpz_cmp_si ((*expr)->value.integer, 0) < 0)
- mpz_set_si ((*expr)->value.integer, 0);
+ gfc_free_expr (e);
+ }
return m;
syntax:
- gfc_error ("Conflict in attributes of function argument at %C");
+ gfc_error ("Scalar INTEGER expression expected at %L", &(*expr)->where);
return MATCH_ERROR;
}
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 74f26b7..dda2d5a 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1939,6 +1939,11 @@ kind_selector:
if (m == MATCH_NO)
m = MATCH_YES; /* No kind specifier found. */
+ /* gfortran may have matched REAL(a=1), which is the keyword form of the
+ intrinsic procedure. */
+ if (ts->type == BT_REAL && m == MATCH_ERROR)
+ m = MATCH_NO;
+
return m;
}