re PR fortran/78021 (Wrong result with optimization on character constant)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 22 Oct 2016 14:04:46 +0000 (14:04 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 22 Oct 2016 14:04:46 +0000 (14:04 +0000)
2016-10-22  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/78021
* gfc_compare_functions:  Strings with different lengths in
argument lists compare unequal.

2016-10-22  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/78021
* gfortran.dg/string_length_3.f90:  New test.

From-SVN: r241440

gcc/fortran/ChangeLog
gcc/fortran/dependency.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/string_length_3.f90 [new file with mode: 0644]

index 406ebb32e936f8a4d5b31ba52c57a7899cf3599a..f5843bf72585159b0ff37fbce398ebb12f3ad8c8 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-22  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/78021
+       * gfc_compare_functions:  Strings with different lengths in
+       argument lists compare unequal.
+
 2016-10-22  Andre Vehreschild  <vehre@gcc.gnu.org>
 
        PR fortran/43366
index 8e78e43083219402c6719db8256a7a78b7e16e7e..82c5e6b573325e4a2b110db1c2b8c7052501435e 100644 (file)
@@ -226,9 +226,26 @@ gfc_dep_compare_functions (gfc_expr *e1, gfc_expr *e2, bool impure_ok)
          if ((args1->expr == NULL) ^ (args2->expr == NULL))
            return -2;
 
-         if (args1->expr != NULL && args2->expr != NULL
-             && gfc_dep_compare_expr (args1->expr, args2->expr) != 0)
-           return -2;
+         if (args1->expr != NULL && args2->expr != NULL)
+           {
+             gfc_expr *e1, *e2;
+             e1 = args1->expr;
+             e2 = args2->expr;
+
+             if (gfc_dep_compare_expr (e1, e2) != 0)
+               return -2;
+
+             /* Special case: String arguments which compare equal can have
+                different lengths, which makes them different in calls to
+                procedures.  */
+             
+             if (e1->expr_type == EXPR_CONSTANT
+                 && e1->ts.type == BT_CHARACTER
+                 && e2->expr_type == EXPR_CONSTANT
+                 && e2->ts.type == BT_CHARACTER
+                 && e1->value.character.length != e2->value.character.length)
+               return -2;
+           }
 
          args1 = args1->next;
          args2 = args2->next;
index 74c2b091c9657da914a1dc135ee40d35d5aa16e9..8b091019af58be765fe2cc8b446e32f77e1304a1 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-22  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/78021
+       * gfortran.dg/string_length_3.f90:  New test.
+
 2016-10-22  Andre Vehreschild  <vehre@gcc.gnu.org>
 
        Forgot to add on original commit.
diff --git a/gcc/testsuite/gfortran.dg/string_length_3.f90 b/gcc/testsuite/gfortran.dg/string_length_3.f90
new file mode 100644 (file)
index 0000000..e745eb9
--- /dev/null
@@ -0,0 +1,19 @@
+! { dg-do run }
+! { dg-options "-ffrontend-optimize -fdump-tree-original" }
+! PR 78021 - calls to mylen were folded after shortening the
+! argument list.
+
+PROGRAM test_o_char
+  implicit none
+  integer :: n
+  n = mylen('c') + mylen('c   ')
+  if (n /= 5) call abort
+CONTAINS
+
+  FUNCTION mylen(c)
+    CHARACTER(len=*),INTENT(in) :: c
+    INTEGER :: mylen
+    mylen=LEN(c)
+  END FUNCTION mylen
+END PROGRAM test_o_char
+! { dg-final { scan-tree-dump-times "__var" 0 "original" } }