On Fri, Nov 13, 2015 at 01:57:13PM -0800, Steve Kargl wrote:
> The attached patch fixes an ICE that occurs in arith.c(gfc_arith_concat)
> because op1 and op2 have incompatible typespecs.  The fix is actually
> implemented in array.c(gfc_match_array_constructor) where the types
> of the elements in a constructor are compared to the typespec that was
> specified in the constructor.  See testcase for examples.  Built
> and regression tested on x86_64-*-freebsd.  OK to commit?
> 
> 2015-11-13  Steven G. Kargl  <ka...@gcc.gnu.org>
> 
>       PR fortran/67803
>       * array.c (gfc_match_array_constructor): If array constructor included
>       a CHARACTER typespec, check array elements for compatible type.
> 
> 2015-11-13  Steven G. Kargl  <ka...@gcc.gnu.org>
>  
>       PR fortran/67803
>       * gfortran.dg/pr67803.f90: New test.
> 

Now with a patch attached.

-- 
Steve
Index: gcc/fortran/array.c
===================================================================
--- gcc/fortran/array.c	(revision 230351)
+++ gcc/fortran/array.c	(working copy)
@@ -1162,6 +1162,35 @@ done:
     {
       expr = gfc_get_array_expr (ts.type, ts.kind, &where);
       expr->ts = ts;
+
+      /* If the typespec is CHARACTER, check that array elements can
+	 be converted.  See PR fortran/67803.  */
+      if (ts.type == BT_CHARACTER)
+	{
+	  gfc_constructor *c;
+
+	  c = gfc_constructor_first (head);
+	  for (; c; c = gfc_constructor_next (c))
+	    {
+	      if (gfc_numeric_ts (&c->expr->ts)
+		  || c->expr->ts.type == BT_LOGICAL)
+		{
+		  gfc_error ("Incompatiable typespec for array element at %L",
+			     &c->expr->where);
+		  return MATCH_ERROR;
+		}
+
+	      /* Special case null().  */
+	      if (c->expr->expr_type == EXPR_FUNCTION
+		  && c->expr->ts.type == BT_UNKNOWN
+		  && strcmp (c->expr->symtree->name, "null") == 0)
+		{
+		  gfc_error ("Incompatiable typespec for array element at %L",
+			     &c->expr->where);
+		  return MATCH_ERROR;
+		}
+	    }
+	}
     }
   else
     expr = gfc_get_array_expr (BT_UNKNOWN, 0, &where);
@@ -1171,6 +1200,7 @@ done:
     expr->ts.u.cl->length_from_typespec = seen_ts;
 
   *result = expr;
+
   return MATCH_YES;
 
 syntax:
Index: gcc/testsuite/gfortran.dg/pr67803.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr67803.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr67803.f90	(working copy)
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! PR fortran/67803
+! Original code submitted by Gerhard Steinmetz
+! <gerhard dot steinmetz dot fortran at t-online dot de >
+!
+program p
+  character(2) :: x(1)
+  x = '0' // [character :: 1]       ! { dg-error "Incompatiable typespec for" }
+  x = '0' // [character :: 1.]      ! { dg-error "Incompatiable typespec for" }
+  x = '0' // [character :: 1d1]     ! { dg-error "Incompatiable typespec for" }
+  x = '0' // [character :: (0.,1.)] ! { dg-error "Incompatiable typespec for" }
+  x = '0' // [character :: .true.]  ! { dg-error "Incompatiable typespec for" }
+  x = '0' // [character :: null()]  ! { dg-error "Incompatiable typespec for" }
+end

Reply via email to