This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] PR29397 and PR29400 - parameter arrays with scalar initializers


:ADDPATCH fortran:

Both these PRs were caused by scalar initializers for parameter arrays
not being expanded into array expressions.  Fixing PR29400 required
the correct shape array for the initializer expression, since rank > 1
is involved.  The testcases are the reporter's.

Bootstrapped and regtested on x86_ia64/FC5 - OK for trunk?

Paul

2006-05-07 Paul Thomas <pault@gcc.gnu.org>

	PR fortran/29397
	PR fortran/29400
	* decl.c (add_init_expr_to_sym): Expand a scalar initializer
	for a parameter array into an array expression with the right
	shape.
	* array.c (spec_dimen_size): Remove static attribute.
	* gfortran.h : Prototype for spec_dimen_size.

2006-05-07 Paul Thomas <pault@gcc.gnu.org>

	PR fortran/29397
	* gfortran.dg/parameter_array_init_1.f90: New test.

	PR fortran/29400
	* gfortran.dg/parameter_array_init_2.f90: New test.

--
"Success is the ability to go from one failure to another with no loss
of enthusiasm."  -  Winston Churchill
Index: gcc/fortran/decl.c
===================================================================
*** gcc/fortran/decl.c	(revision 124499)
--- gcc/fortran/decl.c	(working copy)
*************** add_init_expr_to_sym (const char *name, 
*** 974,980 ****
  
        /* Add initializer.  Make sure we keep the ranks sane.  */
        if (sym->attr.dimension && init->rank == 0)
! 	init->rank = sym->as->rank;
  
        sym->value = init;
        *initp = NULL;
--- 974,1003 ----
  
        /* Add initializer.  Make sure we keep the ranks sane.  */
        if (sym->attr.dimension && init->rank == 0)
! 	{
! 	  mpz_t size;
! 	  gfc_expr *array;
! 	  int n;
! 	  if (sym->attr.flavor == FL_PARAMETER
! 		&& init->expr_type == EXPR_CONSTANT
! 		&& spec_size (sym->as, &size) == SUCCESS
! 		&& mpz_cmp_si (size, 0) > 0)
! 	    {
! 	      array = gfc_start_constructor (init->ts.type, init->ts.kind,
! 					     &init->where);
! 	      for (n = 0; n < (int)mpz_get_si (size); n++)
! 		gfc_append_constructor (array, gfc_copy_expr (init));
! 
! 	      array->shape = gfc_get_shape (sym->as->rank);
! 	      for (n = 0; n < sym->as->rank; n++)
! 		spec_dimen_size (sym->as, n, &array->shape[n]);
! 
! 	      gfc_free_expr (init);
! 	      init = array;
! 	      mpz_clear (size);
! 	    }
! 	  init->rank = sym->as->rank;
! 	}
  
        sym->value = init;
        *initp = NULL;
Index: gcc/fortran/array.c
===================================================================
*** gcc/fortran/array.c	(revision 124499)
--- gcc/fortran/array.c	(working copy)
*************** gfc_get_array_element (gfc_expr *array, 
*** 1714,1720 ****
  /* Get the size of single dimension of an array specification.  The
     array is guaranteed to be one dimensional.  */
  
! static try
  spec_dimen_size (gfc_array_spec *as, int dimen, mpz_t *result)
  {
    if (as == NULL)
--- 1714,1720 ----
  /* Get the size of single dimension of an array specification.  The
     array is guaranteed to be one dimensional.  */
  
! try
  spec_dimen_size (gfc_array_spec *as, int dimen, mpz_t *result)
  {
    if (as == NULL)
Index: gcc/fortran/gfortran.h
===================================================================
*** gcc/fortran/gfortran.h	(revision 124499)
--- gcc/fortran/gfortran.h	(working copy)
*************** void gfc_insert_constructor (gfc_expr *,
*** 2121,2126 ****
--- 2121,2127 ----
  gfc_constructor *gfc_get_constructor (void);
  tree gfc_conv_array_initializer (tree type, gfc_expr * expr);
  try spec_size (gfc_array_spec *, mpz_t *);
+ try spec_dimen_size (gfc_array_spec *, int, mpz_t *);
  int gfc_is_compile_time_shape (gfc_array_spec *);
  
  /* interface.c -- FIXME: some of these should be in symbol.c */
Index: gcc/testsuite/gfortran.dg/parameter_array_init_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/parameter_array_init_1.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/parameter_array_init_1.f90	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ ! { dg-do compile }
+ ! tests the fix for PR29397, in which the initializer for the parameter
+ ! 'J' was not expanded into an array.
+ !
+ ! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ !
+   INTEGER :: K(3) = 1
+   INTEGER, PARAMETER :: J(3) = 2
+   IF (ANY (MAXLOC (K, J<3) .NE. 1)) CALL ABORT ()
+   IF (ANY (J .NE. 2)) CALL ABORT ()
+ END
Index: gcc/testsuite/gfortran.dg/parameter_array_init_2.f90
===================================================================
*** gcc/testsuite/gfortran.dg/parameter_array_init_2.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/parameter_array_init_2.f90	(revision 0)
***************
*** 0 ****
--- 1,26 ----
+ ! { dg-do run }
+ ! { dg-options "-std=gnu" } ! suppress the warning about line 15
+ ! Thrashes the fix for PR29400, where the scalar initializers
+ ! were not expanded to arrays with the appropriate shape.
+ !
+ ! CContributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ !
+   integer,parameter :: i(1,1) = 0, j(2) = 42
+ 
+   if (any (maxloc(j+j,mask=(j==2)) .ne. 0)) call abort ()
+   if (size(j+j) .ne. 2) call abort ()
+   if (minval(j+j) .ne. 84) call abort ()
+   if (minval(j,mask=(j==2)) .ne. huge (j)) call abort ()
+   if (maxval(j+j) .ne. 84) call abort ()
+   if (maxval(j,mask=(j==2)) .ne. -huge (j)-1) call abort ()
+   if (sum(j,mask=j==2) .ne. 0) call abort ()
+   if (sum(j+j) .ne. 168) call abort ()
+   if (product(j+j) .ne. 7056) call abort ()
+   if (any(ubound(j+j) .ne. 2)) call abort ()
+   if (any(lbound(j+j) .ne. 1)) call abort ()
+   if (dot_product(j+j,j) .ne. 7056) call abort ()
+   if (dot_product(j,j+j) .ne. 7056) call abort ()
+   if (count(i==1) .ne. 0) call abort ()
+   if (any(i==1)) call abort ()
+   if (all(i==1)) call abort ()
+   end

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