]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR fortran/78021 (Wrong result with optimization on character constant)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Mon, 24 Oct 2016 22:12:06 +0000 (22:12 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Mon, 24 Oct 2016 22:12:06 +0000 (22:12 +0000)
2016-10-24  Thomas Koenig  <tkoenig@gcc.gnu.org>

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

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

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

From-SVN: r241498

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

index 3c392a69f934e4a821de876ae908ff9adf953e01..1f812f78c95daac7dc5f713fcaa0c0d255490c63 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-24  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       Backport from trunk
+       PR fortran/78021
+       * gfc_compare_functions:  Strings with different lengths in
+       argument lists compare unequal.
+
 2016-10-24  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/71895
index 40adbe4a57f4c9c8c698c792e8bc9a790dcf0e85..37adcc1b9b6f4c6cf9d310ae984f4138c62c38ad 100644 (file)
@@ -227,9 +227,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 d9c8de752bf5978552e3da03636955eedeccdd6b..3700eabf635ec5bd0262bec11b3b31275b025ab9 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-24  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       Backport from trunk
+       PR fortran/78021
+       * gfortran.dg/string_length_3.f90:  New test.
+
 2016-10-24  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/71895
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" } }