Patchwork [Fortran] PR56615 - Wrong-code with TRANSFER of noncontiguous arrays

login
register
mail settings
Submitter Tobias Burnus
Date March 15, 2013, 8:07 a.m.
Message ID <5142D6DD.2090902@net-b.de>
Download mbox | patch
Permalink /patch/227872/
State New
Headers show

Comments

Tobias Burnus - March 15, 2013, 8:07 a.m.
The issue is a regression which exists since GCC 4.4. The fix is rather 
obvious (see also PR).

Build and regtested on x86-64-gnu-linux.
OK for the trunk and the two maintained branches, 4.6 and 4.7?

Tobias
Janus Weil - March 15, 2013, 10:03 a.m.
Hi Tobias,

> The issue is a regression which exists since GCC 4.4. The fix is rather
> obvious (see also PR).
>
> Build and regtested on x86-64-gnu-linux.
> OK for the trunk and the two maintained branches, 4.6 and 4.7?

yes, looks good to me (pretty much obvious).

It seems the 4.8 release is quite close, but I think this should still
be able to go in (not sure if you may need to consult the release
managers at this point). According to
http://gcc.gnu.org/ml/gcc/2013-03/msg00036.html, trunk is still in
release-branch mode, and no RC has been created AFAIK ...

Cheers,
Janus

Patch

2013-03-15  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56615
	* trans-intrinsic.c (gfc_conv_intrinsic_transfer): Pack arrays
	if they are not simply contiguous.

2013-03-15  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56615
	* gfortran.dg/transfer_intrinsic_5.f90: New.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 83e3acf..7905503 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5435,9 +5435,8 @@  gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
       source = gfc_conv_descriptor_data_get (argse.expr);
       source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
 
-      /* Repack the source if not a full variable array.  */
-      if (arg->expr->expr_type == EXPR_VARIABLE
-	      && arg->expr->ref->u.ar.type != AR_FULL)
+      /* Repack the source if not simply contiguous.  */
+      if (!gfc_is_simply_contiguous (arg->expr, false))
 	{
 	  tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
 
diff --git a/gcc/testsuite/gfortran.dg/transfer_intrinsic_5.f90 b/gcc/testsuite/gfortran.dg/transfer_intrinsic_5.f90
new file mode 100644
index 0000000..47be585
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_intrinsic_5.f90
@@ -0,0 +1,50 @@ 
+! { dg-do run }
+!
+! PR fortran/56615
+!
+! Contributed by  Harald Anlauf
+!
+!
+program gfcbug
+  implicit none
+  integer, parameter             :: n = 8
+  integer                        :: i
+  character(len=1), dimension(n) :: a, b
+  character(len=n)               :: s, t
+  character(len=n/2)             :: u
+
+  do i = 1, n
+     a(i) = achar (i-1 + iachar("a"))
+  end do
+!  print *, "# Forward:"
+!  print *, "a=", a
+  s = transfer (a, s)
+!  print *, "s=", s
+  call cmp (a, s)
+!  print *, "  stride = +2:"
+  do i = 1, n/2
+     u(i:i) = a(2*i-1)
+  end do
+!  print *, "u=", u
+  call cmp (a(1:n:2), u)
+!  print *
+!  print *, "# Backward:"
+  b = a(n:1:-1)
+!  print *, "b=", b
+  t = transfer (b, t)
+!  print *, "t=", t
+  call cmp (b, t)
+!  print *, "  stride = -1:"
+  call cmp (a(n:1:-1), t)
+contains
+  subroutine cmp (b, s)
+    character(len=1), dimension(:), intent(in) :: b
+    character(len=*),               intent(in) :: s
+    character(len=size(b))                     :: c
+    c = transfer (b, c)
+    if (c /= s) then
+      print *, "c=", c, "    ", merge ("  ok","BUG!", c == s)
+      call abort ()
+    end if
+  end subroutine cmp
+end program gfcbug