]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/51218 (Potential optimization bug due to implicit_pure?)
authorTobias Burnus <burnus@net-b.de>
Thu, 24 Nov 2011 20:44:28 +0000 (21:44 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Thu, 24 Nov 2011 20:44:28 +0000 (21:44 +0100)
2011-11-24  Tobias Burnus  <burnus@net-b.de>

        PR fortran/51218
        * resolve.c (pure_subroutine): If called subroutine is
        impure, unset implicit_pure.
        (resolve_function): Move impure check to simplify code.

2011-11-24  Tobias Burnus  <burnus@net-b.de>

        PR fortran/51218
        * gfortran.dg/implicit_pure_1.f90: New.

From-SVN: r181699

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

index 956a2a853592909a45358f17ad7163ccccce784d..84c5d7ed4928c6ff2b036c6dffe72ea04938eb30 100644 (file)
@@ -1,3 +1,8 @@
+2011-11-24  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/51218
+       * gfortran.dg/implicit_pure_1.f90: New.
+
 2011-10-26  Release Manager
 
        * GCC 4.6.2 released.
index 4229c8b71824bde3757292b8e3b813ba1c0ed0ec..aed4625980e91cd1afbc805642df4252e71b8e47 100644 (file)
@@ -3132,10 +3132,10 @@ resolve_function (gfc_expr *expr)
                     "procedure within a PURE procedure", name, &expr->where);
          t = FAILURE;
        }
-    }
 
-  if (!pure_function (expr, &name) && name && gfc_implicit_pure (NULL))
-    gfc_current_ns->proc_name->attr.implicit_pure = 0;
+      if (gfc_implicit_pure (NULL))
+       gfc_current_ns->proc_name->attr.implicit_pure = 0;
+    }
 
   /* Functions without the RECURSIVE attribution are not allowed to
    * call themselves.  */
@@ -3195,6 +3195,9 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym)
   else if (gfc_pure (NULL))
     gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name,
               &c->loc);
+
+  if (gfc_implicit_pure (NULL))
+    gfc_current_ns->proc_name->attr.implicit_pure = 0;
 }
 
 
index 7a5c0d3888f1cc15d84556f1aedd863fda4c7933..28fb3a7e5fbf9b2c6e1583a5247454cfd98af5b6 100644 (file)
@@ -1,3 +1,10 @@
+2011-11-24  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/51218
+       * resolve.c (pure_subroutine): If called subroutine is
+       impure, unset implicit_pure.
+       (resolve_function): Move impure check to simplify code.
+
 2011-11-22  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/51265
diff --git a/gcc/testsuite/gfortran.dg/implicit_pure_1.f90 b/gcc/testsuite/gfortran.dg/implicit_pure_1.f90
new file mode 100644 (file)
index 0000000..d4a5a36
--- /dev/null
@@ -0,0 +1,53 @@
+! { dg-do run }
+!
+! PR fortran/51218
+!
+! Contributed by Harald Anlauf
+!
+
+module a
+  implicit none
+  integer :: neval = 0
+contains
+  subroutine inc_eval
+    neval = neval + 1
+  end subroutine inc_eval
+end module a
+
+module b
+  use a
+  implicit none
+contains
+  function f(x) ! Should be implicit pure
+    real :: f
+    real, intent(in) :: x
+    f = x
+  end function f
+
+  function g(x) ! Should NOT be implicit pure
+    real :: g
+    real, intent(in) :: x
+    call inc_eval
+    g = x
+  end function g
+end module b
+
+program gfcbug114a
+  use a
+  use b
+  implicit none
+  real :: x = 1, y = 1, t, u, v, w
+  if (neval /= 0) call abort ()
+  t = f(x)*f(y)
+  if (neval /= 0) call abort ()
+  u = f(x)*f(y) + f(x)*f(y)
+  if (neval /= 0) call abort ()
+  v = g(x)*g(y)
+  if (neval /= 2) call abort ()
+  w = g(x)*g(y) + g(x)*g(y)
+  if (neval /= 6) call abort ()
+  if (t /= 1.0 .or. u /= 2.0 .or. v /= 1.0 .or. w /= 2) call abort ()
+end program gfcbug114a
+
+! { dg-final { scan-module "b" "IMPLICIT_PURE" } }
+! { dg-final { cleanup-modules "b" } }