Patchwork [fortran] Fix PR 49479, reshape with optional arg

login
register
mail settings
Submitter Thomas Koenig
Date June 28, 2011, 7:01 p.m.
Message ID <4E0A24FA.4040303@netcologne.de>
Download mbox | patch
Permalink /patch/102445/
State New
Headers show

Comments

Thomas Koenig - June 28, 2011, 7:01 p.m.
Hi Jerry,
> On 06/27/2011 03:18 PM, Thomas Koenig wrote:
>> Hello world,
>>
>> the attached patch fixes PR 49479, a regression for 4.7 and 4.6. Test
>> case was supplied by Joost, the approach to the patch was suggested by
>> Tobias in comment#4 of the PR. The patch certainly looks safe enough.
>>
>> Regression-tested. OK for trunk and, after a couple of days, for 4.6?
>>
>> Thomas
>>
>
> OK,

After your approval, I realized that I had forgotten the generic
reshape.  I added that as obvious.  Here is what I committed,
revision 175594.

Regards

	Thomas

2011-06-28  Thomas Koenig  <tkoenig@gcc.gnu.org>

         PR fortran/49479
         * m4/reshape.m4: If source allocation is smaller than one, set it
         to one.
         * intrinsics/reshape_generic.c:  Likewise.
         * generated/reshape_r16.c: Regenerated.
         * generated/reshape_c4.c: Regenerated.
         * generated/reshape_c16.c: Regenerated.
         * generated/reshape_c8.c: Regenerated.
         * generated/reshape_r4.c: Regenerated.
         * generated/reshape_i4.c: Regenerated.
         * generated/reshape_r10.c: Regenerated.
         * generated/reshape_r8.c: Regenerated.
         * generated/reshape_c10.c: Regenerated.
         * generated/reshape_i8.c: Regenerated.
         * generated/reshape_i16.c: Regenerated.

2011-06-28  Thomas Koenig  <tkoenig@gcc.gnu.org>

         PR fortran/49479
         * gfortran.dg/reshape_zerosize_3.f90:  New test.
! { dg-do run }
! PR 49479 - this used not to print anything.
! Test case by Joost VandeVondele.
MODULE M1
  IMPLICIT NONE
  type foo
     character(len=5) :: x
  end type foo
CONTAINS
  SUBROUTINE S1(data)
    INTEGER, DIMENSION(:), INTENT(IN), &
         OPTIONAL                               :: DATA
    character(20) :: line
    IF (.not. PRESENT(data)) call abort
    write (unit=line,fmt='(I5)') size(data)
    if (line /= '    0               ') call abort
  END SUBROUTINE S1

  subroutine s_type(data)
    type(foo), dimension(:), intent(in), optional :: data
    character(20) :: line
    IF (.not. PRESENT(data)) call abort
    write (unit=line,fmt='(I5)') size(data)
    if (line /= '    0               ') call abort
  end subroutine s_type

  SUBROUTINE S2(N)
    INTEGER :: N
    INTEGER, ALLOCATABLE, DIMENSION(:, :)    :: blki
    type(foo), allocatable, dimension(:, :)  :: bar
    ALLOCATE(blki(3,N))
    allocate (bar(3,n))
    blki=0
    CALL S1(RESHAPE(blki,(/3*N/)))
    call s_type(reshape(bar, (/3*N/)))
  END SUBROUTINE S2

END MODULE M1

USE M1
CALL S2(0)
END
! { dg-final { cleanup-modules "m1" } }

Patch

Index: m4/reshape.m4
===================================================================
--- m4/reshape.m4	(Revision 175593)
+++ m4/reshape.m4	(Arbeitskopie)
@@ -101,6 +101,8 @@ 
 
   if (ret->data == NULL)
     {
+      index_type alloc_size;
+
       rs = 1;
       for (n = 0; n < rdim; n++)
 	{
@@ -111,7 +113,13 @@ 
 	  rs *= rex;
 	}
       ret->offset = 0;
-      ret->data = internal_malloc_size ( rs * sizeof ('rtype_name`));
+
+      if (unlikely (rs < 1))
+        alloc_size = 1;
+      else
+        alloc_size = rs * sizeof ('rtype_name`);
+
+      ret->data = internal_malloc_size (alloc_size);
       ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
     }
 
Index: intrinsics/reshape_generic.c
===================================================================
--- intrinsics/reshape_generic.c	(Revision 175593)
+++ intrinsics/reshape_generic.c	(Arbeitskopie)
@@ -85,6 +85,8 @@ 
 
   if (ret->data == NULL)
     {
+      index_type alloc_size;
+
       rs = 1;
       for (n = 0; n < rdim; n++)
 	{
@@ -95,7 +97,14 @@ 
 	  rs *= rex;
 	}
       ret->offset = 0;
-      ret->data = internal_malloc_size ( rs * size );
+
+      if (unlikely (rs < 1))
+	alloc_size = 1;
+      else
+	alloc_size = rs * size;
+
+      ret->data = internal_malloc_size (alloc_size);
+
       ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
     }