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 |
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?
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.
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
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;