diff options
author | Steven G. Kargl <kargl@gcc.gnu.org> | 2015-10-17 16:50:47 +0000 |
---|---|---|
committer | Steven G. Kargl <kargl@gcc.gnu.org> | 2015-10-17 16:50:47 +0000 |
commit | 98a819ea15fdaf6e5d8efb6e002bec70628aaee5 (patch) | |
tree | 538dc3982c7de62c55c6e43407ca68fd6c995ae1 /gcc/fortran/decl.c | |
parent | 767dc529b7ed5926d4900a4182826967beb8c2c2 (diff) | |
download | gcc-98a819ea15fdaf6e5d8efb6e002bec70628aaee5.zip gcc-98a819ea15fdaf6e5d8efb6e002bec70628aaee5.tar.gz gcc-98a819ea15fdaf6e5d8efb6e002bec70628aaee5.tar.bz2 |
re PR fortran/67987 (ICE on declaring and initializing character with negative len)
2015-10-17 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/67987
* decl.c (char_len_param_value): Unwrap unlong line. If LEN < 0,
force it to zero per the Fortran 90, 95, 2003, and 2008 Standards.
* resolve.c (gfc_resolve_substring_charlen): Unwrap unlong line.
If 'start' is larger than 'end', length of substring is negative,
so explicitly set it to zero.
(resolve_charlen): Remove -Wsurprising warning. Update comment to
reflect that the text is from the F2008 standard.
2015-10-17 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/67987
* gfortran.df/pr67987.f90: New test.
* gfortran.dg/char_length_2.f90: Update testcase.
From-SVN: r228933
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r-- | gcc/fortran/decl.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 39e0805..4871b7c 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -697,8 +697,7 @@ char_len_param_value (gfc_expr **expr, bool *deferred) if (gfc_match_char (':') == MATCH_YES) { - if (!gfc_notify_std (GFC_STD_F2003, "deferred type " - "parameter at %C")) + if (!gfc_notify_std (GFC_STD_F2003, "deferred type parameter at %C")) return MATCH_ERROR; *deferred = true; @@ -708,11 +707,13 @@ char_len_param_value (gfc_expr **expr, bool *deferred) m = gfc_match_expr (expr); - if (m == MATCH_YES - && !gfc_expr_check_typed (*expr, gfc_current_ns, false)) + if (m == MATCH_NO || m == MATCH_ERROR) + return m; + + if (!gfc_expr_check_typed (*expr, gfc_current_ns, false)) return MATCH_ERROR; - if (m == MATCH_YES && (*expr)->expr_type == EXPR_FUNCTION) + if ((*expr)->expr_type == EXPR_FUNCTION) { if ((*expr)->value.function.actual && (*expr)->value.function.actual->expr->symtree) @@ -731,6 +732,15 @@ char_len_param_value (gfc_expr **expr, bool *deferred) } } } + + /* 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); + return m; syntax: |