2010-09-06 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 Sep 2010 19:43:58 +0000 (19:43 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 Sep 2010 19:43:58 +0000 (19:43 +0000)
PR fortran/34145
* trans-expr.c (gfc_conv_substring):  If start and end
of the string reference are equal, set the length to one.

2010-09-06  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/34145
* gfortran.dg/char_length_17.f90:  New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163932 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/trans-expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/char_length_17.f90 [new file with mode: 0644]

index 26974bb..d35cedc 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-06  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/34145
+       * trans-expr.c (gfc_conv_substring):  If start and end
+       of the string reference are equal, set the length to one.
+
 2010-09-06  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/45560
index 8f1bddc..479c807 100644 (file)
@@ -463,12 +463,20 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
       gfc_free (msg);
     }
 
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
-                        end.expr, start.expr);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
-                        build_int_cst (gfc_charlen_type_node, 1), tmp);
-  tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node, tmp,
-                        build_int_cst (gfc_charlen_type_node, 0));
+  /* If the start and end expressions are equal, the length is one.  */
+  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);
+  else
+    {
+      tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
+                            end.expr, start.expr);
+      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
+                            build_int_cst (gfc_charlen_type_node, 1), tmp);
+      tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
+                            tmp, build_int_cst (gfc_charlen_type_node, 0));
+    }
+
   se->string_length = tmp;
 }
 
index 4805390..362f5d1 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-06  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/34145
+       * gfortran.dg/char_length_17.f90:  New test.
+
 2010-09-06  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/45200
diff --git a/gcc/testsuite/gfortran.dg/char_length_17.f90 b/gcc/testsuite/gfortran.dg/char_length_17.f90
new file mode 100644 (file)
index 0000000..5752dd1
--- /dev/null
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR 34145 - the length of the string should be simplified to one,
+! no library call for string comparison is necessary.
+program main
+  character (len=5) :: c
+  integer(kind=8) :: i
+  i = 3
+  c(i:i) = 'a'
+  c(i+1:i+1) = 'b'
+  if (c(i:i) /= 'a') call abort ()
+  if (c(i+1:i+1) /= 'b') call abort ()
+end program main
+! { dg-final { scan-tree-dump-times "gfortran_compare_string" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }