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] PR29758 - Runtime segfault in RESHAPE with insufficient elements in SOURCE


:ADDPATCH fortran:

This patch checks to see if there are enough elements in reshape's source to match shape, when shape is a constant array and source has a constant shape. It is a self explanatory bit of hacking in check.c. The testcase checks two obvious errors and checks that a correct one goes through.

Regtested Suse10.1/amd64.

OK for trunk, 4.2 and 4.1?

Paul

2006-11-08 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/29758
   * check.c (gfc_check_reshape): Check that there are enough
   elements in the source array as to be able to fill an array
   defined by shape, when pad is absent.

2006-11-08 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/29758
   * gfortran.dg/reshape_source_size_1.f90: New test.


Index: gcc/fortran/check.c
===================================================================
*** gcc/fortran/check.c	(revision 118597)
--- gcc/fortran/check.c	(working copy)
*************** gfc_check_reshape (gfc_expr * source, gf
*** 2110,2115 ****
--- 2110,2116 ----
  		   gfc_expr * pad, gfc_expr * order)
  {
    mpz_t size;
+   mpz_t nelems;
    int m;
  
    if (array_check (source, 0) == FAILURE)
*************** gfc_check_reshape (gfc_expr * source, gf
*** 2149,2154 ****
--- 2150,2187 ----
    if (order != NULL && array_check (order, 3) == FAILURE)
      return FAILURE;
  
+   if (pad == NULL
+ 	&& shape->expr_type == EXPR_ARRAY
+ 	&& gfc_is_constant_expr (shape)
+ 	&& !(source->expr_type == EXPR_VARIABLE
+ 	       && source->symtree->n.sym->as
+ 	       && source->symtree->n.sym->as->type == AS_ASSUMED_SIZE))
+     {
+       /* Check the match in size between source and destination.  */
+       if (gfc_array_size (source, &nelems) == SUCCESS)
+ 	{
+ 	  gfc_constructor *c;
+ 	  bool test;
+ 
+ 	  c = shape->value.constructor;
+ 	  mpz_init_set_ui (size, 1);
+ 	  for (; c; c = c->next)
+ 	    mpz_mul (size, size, c->expr->value.integer);
+ 
+ 	  test = mpz_cmp (nelems, size) < 0 && mpz_cmp_ui (size, 0) > 0;
+ 	  mpz_clear (nelems);
+ 	  mpz_clear (size);
+ 
+ 	  if (test)
+ 	    {
+ 	      gfc_error ("Without padding, there are not enough elements in the "
+ 			 "intrinsic RESHAPE source at %L to match the shape",
+ 			 &source->where);
+ 	      return FAILURE;
+ 	    }
+ 	}
+     }
+ 
    return SUCCESS;
  }
  
Index: gcc/testsuite/gfortran.dg/reshape_source_size_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/reshape_source_size_1.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/reshape_source_size_1.f90	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ ! { dg-do compile }
+ ! Tests patch for PR29758, which arose from PR29431.  There was no check that there
+ ! were enough elements in the source to match the shape.
+ !
+ ! Contributed by Paul Thomas  <pault@gcc.gnu.org>
+ !
+    real :: a(2,2), b = 1.0, c(3), d(4)
+    a = reshape ([b], [2,2]) ! { dg-error "not enough elements" }
+    a = reshape (c, [2,2])   ! { dg-error "not enough elements" }
+    a = reshape (d, [2,2])
+ end

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