From d6598cf719fb63ead5618cf8908218519e82cc3e Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sun, 4 Sep 2016 16:17:55 +0000 Subject: [PATCH] re PR fortran/71902 (Unneeded temporary on reallocatable character assignment) 2016-09-04 Thomas Koenig PR fortran/71902 * frontend-passes.c (realloc_string_callback): Also check for the lhs being deferred. Name temporary variable "realloc_string". 2016-09-04 Thomas Koenig PR fortran/71902 * gfortran.dg/dependency_47.f90: New test. * gfortran.dg/dependency_49.f90: New test. From-SVN: r239977 --- gcc/fortran/frontend-passes.c | 19 +++++++++++++++++-- gcc/testsuite/gfortran.dg/dependency_47.f90 | 14 ++++++++++++++ gcc/testsuite/gfortran.dg/dependency_49.f90 | 14 ++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/dependency_47.f90 create mode 100644 gcc/testsuite/gfortran.dg/dependency_49.f90 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index c138f4d7c77..cd109791075 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -164,19 +164,34 @@ realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, gfc_expr *expr1, *expr2; gfc_code *co = *c; gfc_expr *n; + gfc_ref *ref; + bool found_substr; if (co->op != EXEC_ASSIGN) return 0; expr1 = co->expr1; if (expr1->ts.type != BT_CHARACTER || expr1->rank != 0 - || !expr1->symtree->n.sym->attr.allocatable) + || !gfc_expr_attr(expr1).allocatable + || !expr1->ts.deferred) return 0; expr2 = gfc_discard_nops (co->expr2); if (expr2->expr_type != EXPR_VARIABLE) return 0; + found_substr = false; + for (ref = expr2->ref; ref; ref = ref->next) + { + if (ref->type == REF_SUBSTRING) + { + found_substr = true; + break; + } + } + if (!found_substr) + return 0; + if (!gfc_check_dependency (expr1, expr2, true)) return 0; @@ -190,7 +205,7 @@ realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, current_code = c; inserted_block = NULL; changed_statement = NULL; - n = create_var (expr2, "trim"); + n = create_var (expr2, "realloc_string"); co->expr2 = n; return 0; } diff --git a/gcc/testsuite/gfortran.dg/dependency_47.f90 b/gcc/testsuite/gfortran.dg/dependency_47.f90 new file mode 100644 index 00000000000..4888771c183 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_47.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! Make sure there is only one instance of a temporary variable here. +! { dg-options "-fdump-tree-original" } + +SUBROUTINE prtdata(ilen) + INTEGER :: ilen + character(len=ilen), allocatable :: cline(:) + allocate(cline(2)) + cline(1) = 'a' + cline(1)(2:3) = cline(1)(1:2) + cline(2) = cline(1) + print *,c +END SUBROUTINE prtdata +! { dg-final { scan-tree-dump-not "__var_" "original" } } diff --git a/gcc/testsuite/gfortran.dg/dependency_49.f90 b/gcc/testsuite/gfortran.dg/dependency_49.f90 new file mode 100644 index 00000000000..73d517e8f76 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_49.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! PR fortran/71902 - make sure that component references are followed +! for dependency analysis. +program main + type foo + character(len=:), allocatable :: x + end type foo + type(foo) :: a + a%x = 'asdf' + a%x = a%x(2:3) + print *,a%x +end program main +! { dg-final { scan-tree-dump-times "__var_1" 4 "original" } } -- 2.30.2