https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107000
--- Comment #9 from kargl at gcc dot gnu.org ---
(In reply to kargl from comment #8)
> (In reply to anlauf from comment #7)
> > (In reply to Steve Kargl from comment #6)
> > > Yes, that would work! I was thinking of something more complex
> > > such as looking at the types of the operand(s), but simplification
> > > probably handles +1 and -1 correctly and punts on +'1' and -'1'.
> >
> > I played some more and found that we would regress on e.g.
> >
> > print *, [real :: 1, +real(2.0)]
> >
> > while
> >
> > print *, [real :: 1, real(2.0)]
> >
> > is fine.
> >
> > So we need a better solution...
>
> This is the type of solution I had in mind. It allows the above
> and catches +.false. and -.true.
>
> diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
> index bbdb5b392fc..8b689f28612 100644
> --- a/gcc/fortran/array.cc
> +++ b/gcc/fortran/array.cc
> @@ -1205,6 +1205,21 @@ walk_array_constructor (gfc_typespec *ts,
> gfc_constructor_base head)
> for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
> {
> e = c->expr;
> +
> + /* Special case unary operators to catch [real :: +'1']. */
> + if (e->expr_type == EXPR_OP && e->ts.type == BT_UNKNOWN)
> + {
> + gfc_expr *op1 = e->value.op.op1;
> + if ((op1->value.op.op == INTRINSIC_UMINUS
> + || op1->value.op.op == INTRINSIC_UPLUS)
> + && !gfc_numeric_ts (&op1->ts))
> + {
> + gfc_error("Invalid operand of unary operator at %L",
> + &op1->where);
> + return MATCH_ERROR;
> + }
> + }
> +
> if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
> && !e->ref && e->value.constructor)
> {
>
> Unfortunately, it ICEs with
>
> print *, [real :: 1, +(.true)]
This catches the parenthesis.
diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index bbdb5b392fc..21027844f84 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -1205,6 +1205,24 @@ walk_array_constructor (gfc_typespec *ts,
gfc_constructor_base head)
for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
{
e = c->expr;
+
+ /* Special case unary operators to catch [real :: +'1']. */
+ if (e->expr_type == EXPR_OP && e->ts.type == BT_UNKNOWN)
+ {
+ gfc_expr *op1 = e->value.op.op1;
+ if ((op1->value.op.op == INTRINSIC_UMINUS
+ || op1->value.op.op == INTRINSIC_UPLUS
+ || (op1->expr_type == EXPR_OP
+ && op1->value.op.op == INTRINSIC_PARENTHESES))
+ && (op1->ts.type == BT_CHARACTER
+ || op1->ts.type == BT_LOGICAL))
+ {
+ gfc_error("Invalid operand of unary operator at %L",
+ &op1->where);
+ return MATCH_ERROR;
+ }
+ }
+
if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
&& !e->ref && e->value.constructor)
{