diff options
author | Steven G. Kargl <kargl@gcc.gnu.org> | 2015-10-24 16:20:26 +0000 |
---|---|---|
committer | Steven G. Kargl <kargl@gcc.gnu.org> | 2015-10-24 16:20:26 +0000 |
commit | 8d48826b99b81b7ed96c5db08ec8334a2b0c6557 (patch) | |
tree | fc9895b536072c30abae69ea95b29645078ed28c /gcc/fortran | |
parent | ae1158c42534a9becfb51585b9b69df8d0d13a10 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fortran/array.c | 8 | ||||
-rw-r--r-- | gcc/fortran/decl.c | 67 | ||||
-rw-r--r-- | gcc/fortran/match.c | 5 |
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; } |