This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, Fortran] PR fortran/38887: Fix MVBITS with runtime zero-length array


Hi all,

this "trivial" patch fixes PR 38887, where a call to MVBITS aborted at runtime if the array was empty (but this not detected at runtime).

This regression was introduced by my wrong-code fix for MVBITS; prior to it, elemental dependencies in the arguments to MVBITS were simply ignored, leading to that wrong-code bug. Now, gfc_conv_elemental_dependencies is called which in turn called internal_unpack for copying the result back after the whole evaluation. internal_unpack however aborted when its argument was empty.

I'm not completely sure why it was done that way, as the "ordinary" unpack library function simply returns in this case; my patch changes internal_unpack to do so, also. I believe this is the best solution and should not hurt; my guess is that the abort() was introduced first simply because it was (probably) not possible at that time that internal_unpack could be called with empty arrays. Now it is, and instead of generating runtime-check code for this and call internal_unpack only if the array is not empty, this seems to be the best solution. Comments on this welcome though, if someone can point me out why the abort() was there!

I did exclude the regenerated files from the patch, hope this is ok. Regression-testing on gnu/linux-x86-32 (but there shouldn't be any) at the moment. Ok for trunk if no failures?

Cheers,
Daniel

--
Done:  Arc-Bar-Cav-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri-Ran
2009-01-21  Daniel Kraft  <d@domob.eu>

	* trans-stmt.c (gfc_conv_elemental_dependencies):  Cleaned up comment.

2009-01-21  Daniel Kraft  <d@domob.eu>

	PR fortran/38887
	* runtime/in_unpack_generic.c (internal_unpack):  Return instead of
	abort when called with empty array.
	* m4/in_unpack.m4:  Ditto.
        * generated/in_unpack_i1.c:  Regenerated.
        * generated/in_unpack_i2.c:  Regenerated.
        * generated/in_unpack_i4.c:  Regenerated.
        * generated/in_unpack_i8.c:  Regenerated.
        * generated/in_unpack_i16.c: Regenerated.
        * generated/in_unpack_r4.c:  Regenerated.
        * generated/in_unpack_r8.c:  Regenerated.
        * generated/in_unpack_r10.c: Regenerated.
        * generated/in_unpack_r16.c: Regenerated.
        * generated/in_unpack_c4.c:  Regenerated.
        * generated/in_unpack_c8.c:  Regenerated.
        * generated/in_unpack_c10.c: Regenerated.
        * generated/in_unpack_c16.c: Regenerated.

2009-01-21  Daniel Kraft  <d@domob.eu>

	PR fortran/38887
	* gfortran.dg/mvbits_5.f90:  New test.
Index: gcc/fortran/trans-stmt.c
===================================================================
--- gcc/fortran/trans-stmt.c	(revision 143527)
+++ gcc/fortran/trans-stmt.c	(working copy)
@@ -311,14 +311,11 @@ gfc_conv_elemental_dependencies (gfc_se 
 	  info->offset = gfc_create_var (gfc_array_index_type, NULL);	  
 	  gfc_add_modify (&se->pre, info->offset, offset);
 
-
 	  /* Copy the result back using unpack.  */
 	  tmp = build_call_expr (gfor_fndecl_in_unpack, 2, parmse.expr, data);
 	  gfc_add_expr_to_block (&se->post, tmp);
 
-	  /* XXX: This is possibly not needed; but isn't it cleaner this way? */
 	  gfc_add_block_to_block (&se->pre, &parmse.pre);
-
 	  gfc_add_block_to_block (&se->post, &parmse.post);
 	  gfc_add_block_to_block (&se->post, &temp_post);
 	}
Index: libgfortran/runtime/in_unpack_generic.c
===================================================================
--- libgfortran/runtime/in_unpack_generic.c	(revision 143527)
+++ libgfortran/runtime/in_unpack_generic.c	(working copy)
@@ -178,12 +178,12 @@ internal_unpack (gfc_array_char * d, con
       stride[n] = d->dim[n].stride;
       extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
       if (extent[n] <= 0)
-        abort ();
+	return;
 
       if (dsize == stride[n])
-        dsize *= extent[n];
+	dsize *= extent[n];
       else
-        dsize = 0;
+	dsize = 0;
     }
 
   src = s;
Index: libgfortran/m4/in_unpack.m4
===================================================================
--- libgfortran/m4/in_unpack.m4	(revision 143527)
+++ libgfortran/m4/in_unpack.m4	(working copy)
@@ -63,12 +63,12 @@ internal_unpack_'rtype_ccode` ('rtype` *
       stride[n] = d->dim[n].stride;
       extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
       if (extent[n] <= 0)
-        abort ();
+	return;
 
       if (dsize == stride[n])
-        dsize *= extent[n];
+	dsize *= extent[n];
       else
-        dsize = 0;
+	dsize = 0;
     }
 
   if (dsize != 0)
Index: gcc/testsuite/gfortran.dg/mvbits_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/mvbits_5.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/mvbits_5.f90	(revision 0)
@@ -0,0 +1,17 @@
+! { dg-do run }
+
+! PR fortran/38887
+! This aborted at runtime for the runtime zero-sized array arguments.
+
+! Contributed by Dick Hendrickson <dick.hendrickson@gmail.com>
+
+program try_ya0013
+  integer ida(9)
+  call ya0013(ida,1,5,6)
+end program
+
+SUBROUTINE YA0013(IDA,nf1,nf5,nf6)
+  INTEGER IDA(9)
+  IDA = 1
+  CALL MVBITS(IDA(NF5:NF1), 0, 1, IDA(NF6:NF1),2)
+END SUBROUTINE

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]