diff mbox series

[fortran] Fix PR 65428, ICE on nested empty array constructors

Message ID a57db93e-17b1-ebc5-b3ca-f9888353b51b@netcologne.de
State New
Headers show
Series [fortran] Fix PR 65428, ICE on nested empty array constructors | expand

Commit Message

Thomas Koenig Jan. 2, 2020, 10:35 p.m. UTC
Hello world,

the attached patch fixes an ICE where an array constructor
containing an empty array constructor with a type didn't
get the type from the inner constructor.

The solution is to stash the type away in yet another variable
and only use it if the constructor turns out to be empty, and
the type has not been set some other way.

Regression-tested. OK for trunk?

Regards

	Thomas

Save typespec for empty array constructor.

2020-01-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/65428
	* array.c (empty_constructor): New variable.
	(empty_ts): New variable.
	(expand_constructor): Save typespec in empty_ts.
	Unset empty_constructor if there is an element.
	(gfc_expand_constructor): Initialize empty_constructor
	and empty_ts.  If there was no explicit constructor
	type and the constructor is empty, take the type from
	empty_ts.

2020-01-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/65428
	* gfortran.dg/zero_sized_11.f90: New test.

Comments

Thomas Koenig Jan. 8, 2020, 5:56 a.m. UTC | #1
Am 02.01.20 um 23:35 schrieb Thomas Koenig:
> Hello world,
> 
> the attached patch fixes an ICE where an array constructor
> containing an empty array constructor with a type didn't
> get the type from the inner constructor.
> 
> The solution is to stash the type away in yet another variable
> and only use it if the constructor turns out to be empty, and
> the type has not been set some other way.
> 
> Regression-tested. OK for trunk?

Ping?
Tobias Burnus Jan. 8, 2020, 1:53 p.m. UTC | #2
Hello Thomas,

sorry for the belated review. I am not completely happy about the 
introduction of yet another two global variables, but I also do not see 
an easy way out. Hence: OK.

I was playing around with the following test case – you might consider 
to add them as well. (I would exclude the error item, however.)

Cheers,

Tobias

! C7110  (R770) If type-spec is omitted, each ac-value expression in the
! array-constructor shall have the same declared type and kind type 
parameters

! Should be fine as there is either no or only one ac-value:
print *, [[integer ::],[real::]]
print *, [[integer ::],[real::], [1], [real ::]]
print *, [[integer ::],[real::], ["ABC"], [real ::]] // "ABC"
print *, [integer :: [integer ::],[real::]]

! Old but for completeness:
! OK - accepted
print *, [integer :: [1],[1.0]]
! OK – "Error: Element in INTEGER(4) array constructor at (1) is REAL(4)"
print *, [[1],[1.0]]
end


On 1/2/20 11:35 PM, Thomas Koenig wrote:
> The solution is to stash the type away in yet another variable
> and only use it if the constructor turns out to be empty, and
> the type has not been set some other way.
>
> Regression-tested. OK for trunk?
>
> Save typespec for empty array constructor.
>
> 2020-01-02  Thomas Koenig  <tkoenig@gcc.gnu.org>
>
>     PR fortran/65428
>     * array.c (empty_constructor): New variable.
>     (empty_ts): New variable.
>     (expand_constructor): Save typespec in empty_ts.
>     Unset empty_constructor if there is an element.
>     (gfc_expand_constructor): Initialize empty_constructor
>     and empty_ts.  If there was no explicit constructor
>     type and the constructor is empty, take the type from
>     empty_ts.
>
> 2020-01-02  Thomas Koenig  <tkoenig@gcc.gnu.org>
>
>     PR fortran/65428
>     * gfortran.dg/zero_sized_11.f90: New test.
Thomas Koenig Jan. 9, 2020, 9 p.m. UTC | #3
Hi Tobias,

> I am not completely happy about the introduction of yet another two 
> global variables, but I also do not see an easy way out. Hence: OK.

Actually, I wasn't too happy myself, but, like you, I didn't find
anything better.

> I was playing around with the following test case – you might consider 
> to add them as well. (I would exclude the error item, however.)

I have also added this as a test case.

Committed as r280063 (without the spaces at the end of the
lines that you pointed out in a separate mail).

Thanks for the review!

Regards

	Thomas
diff mbox series

Patch

Index: array.c
===================================================================
--- array.c	(Revision 279821)
+++ array.c	(Arbeitskopie)
@@ -1759,7 +1759,12 @@  cleanup:
   return t;
 }
 
+/* Variables for noticing if all constructors are empty, and
+   if any of them had a type.  */
 
+static bool empty_constructor;
+static gfc_typespec empty_ts;
+
 /* Expand a constructor into constant constructors without any
    iterators, calling the work function for each of the expanded
    expressions.  The work function needs to either save or free the
@@ -1782,6 +1787,9 @@  expand_constructor (gfc_constructor_base base)
 
       e = c->expr;
 
+      if (empty_constructor)
+	empty_ts = e->ts;
+
       if (e->expr_type == EXPR_ARRAY)
 	{
 	  if (!expand_constructor (e->value.constructor))
@@ -1790,6 +1798,7 @@  expand_constructor (gfc_constructor_base base)
 	  continue;
 	}
 
+      empty_constructor = false;
       e = gfc_copy_expr (e);
       if (!gfc_simplify_expr (e, 1))
 	{
@@ -1873,6 +1882,8 @@  gfc_expand_constructor (gfc_expr *e, bool fatal)
 
   iter_stack = NULL;
 
+  empty_constructor = true;
+  gfc_clear_ts (&empty_ts);
   current_expand.expand_work_function = expand;
 
   if (!expand_constructor (e->value.constructor))
@@ -1882,6 +1893,13 @@  gfc_expand_constructor (gfc_expr *e, bool fatal)
       goto done;
     }
 
+  /* If we don't have an explicit constructor type, and there
+     were only empty constructors, then take the type from
+     them.  */
+  
+  if (constructor_ts.type == BT_UNKNOWN && empty_constructor)
+    e->ts = empty_ts;
+  
   gfc_constructor_free (e->value.constructor);
   e->value.constructor = current_expand.base;