aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2019-02-09 17:25:23 +0000
committerHarald Anlauf <anlauf@gcc.gnu.org>2019-02-09 17:25:23 +0000
commit1fe27030ff6424736ddda42874a018d6bc35db70 (patch)
treecd215e137ab074f7b775c4f7669e2327ff4b535d /gcc/fortran/resolve.c
parent5585759fdb6cc1e870670970473b789b3b920961 (diff)
downloadgcc-1fe27030ff6424736ddda42874a018d6bc35db70.zip
gcc-1fe27030ff6424736ddda42874a018d6bc35db70.tar.gz
gcc-1fe27030ff6424736ddda42874a018d6bc35db70.tar.bz2
re PR fortran/89077 (ICE using * as len specifier for character parameter)
2019-02-09 Harald Anlauf <anlauf@gmx.de> PR fortran/89077 * resolve.c (gfc_resolve_substring_charlen): Check substring length for constantness prior to general calculation of length. PR fortran/89077 * gfortran.dg/substr_simplify.f90: New test. From-SVN: r268726
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 92d27fc..3a8f402 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -4965,6 +4965,7 @@ gfc_resolve_substring_charlen (gfc_expr *e)
gfc_ref *char_ref;
gfc_expr *start, *end;
gfc_typespec *ts = NULL;
+ mpz_t diff;
for (char_ref = e->ref; char_ref; char_ref = char_ref->next)
{
@@ -5016,11 +5017,25 @@ gfc_resolve_substring_charlen (gfc_expr *e)
return;
}
- /* Length = (end - start + 1). */
- e->ts.u.cl->length = gfc_subtract (end, start);
- e->ts.u.cl->length = gfc_add (e->ts.u.cl->length,
- gfc_get_int_expr (gfc_charlen_int_kind,
- NULL, 1));
+ /* Length = (end - start + 1).
+ Check first whether it has a constant length. */
+ if (gfc_dep_difference (end, start, &diff))
+ {
+ gfc_expr *len = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
+ &e->where);
+
+ mpz_add_ui (len->value.integer, diff, 1);
+ mpz_clear (diff);
+ e->ts.u.cl->length = len;
+ /* The check for length < 0 is handled below */
+ }
+ else
+ {
+ e->ts.u.cl->length = gfc_subtract (end, start);
+ e->ts.u.cl->length = gfc_add (e->ts.u.cl->length,
+ gfc_get_int_expr (gfc_charlen_int_kind,
+ NULL, 1));
+ }
/* F2008, 6.4.1: Both the starting point and the ending point shall
be within the range 1, 2, ..., n unless the starting point exceeds