diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2013-03-28 21:30:26 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2013-03-28 21:30:26 +0000 |
commit | eab19a1a95cfba787426931c9cb264a50f4983e4 (patch) | |
tree | de0dd9008c209a681b4e6c663313253716f5df2d /gcc/fortran/trans-expr.c | |
parent | 4099436d98dcdd96a0cbfd4332da1ddc961ba7f7 (diff) | |
download | gcc-eab19a1a95cfba787426931c9cb264a50f4983e4.zip gcc-eab19a1a95cfba787426931c9cb264a50f4983e4.tar.gz gcc-eab19a1a95cfba787426931c9cb264a50f4983e4.tar.bz2 |
re PR fortran/45159 (Unnecessary temporaries)
2013-03-28 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/45159
* gfortran.h (gfc_dep_difference): Add prototype.
* dependency.c (discard_nops): New function.
(gfc_dep_difference): New function.
(check_section_vs_section): Use gfc_dep_difference
to calculate the difference of starting indices.
* trans-expr.c (gfc_conv_substring): Use
gfc_dep_difference to calculate the length of
substrings where possible.
2013-03-28 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/45159
* gfortran.dg/string_length_2.f90: New test.
* gfortran.dg/dependency_41.f90: New test.
From-SVN: r197217
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r-- | gcc/fortran/trans-expr.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 06afc4f..d0a9446 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1437,6 +1437,7 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind, gfc_se start; gfc_se end; char *msg; + mpz_t length; type = gfc_get_character_type (kind, ref->u.ss.length); type = build_pointer_type (type); @@ -1520,10 +1521,19 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind, free (msg); } - /* If the start and end expressions are equal, the length is one. */ + /* Try to calculate the length from the start and end expressions. */ if (ref->u.ss.end - && gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) == 0) - tmp = build_int_cst (gfc_charlen_type_node, 1); + && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length)) + { + int i_len; + + i_len = mpz_get_si (length) + 1; + if (i_len < 0) + i_len = 0; + + tmp = build_int_cst (gfc_charlen_type_node, i_len); + mpz_clear (length); /* Was initialized by gfc_dep_difference. */ + } else { tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node, |