aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2013-03-28 21:30:26 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2013-03-28 21:30:26 +0000
commiteab19a1a95cfba787426931c9cb264a50f4983e4 (patch)
treede0dd9008c209a681b4e6c663313253716f5df2d /gcc/fortran/trans-expr.c
parent4099436d98dcdd96a0cbfd4332da1ddc961ba7f7 (diff)
downloadgcc-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.c16
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,