case ARITH_WRONGCONCAT:
p = G_("Illegal type in character concatenation at %L");
break;
+ case ARITH_INVALID_TYPE:
+ p = G_("Invalid type in arithmetic operation at %L");
+ break;
default:
gfc_internal_error ("gfc_arith_error(): Bad error code");
head = gfc_constructor_copy (op->value.constructor);
for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
{
- rc = reduce_unary (eval, c->expr, &r);
+ if (c->expr->expr_type == EXPR_OP && c->expr->ts.type == BT_UNKNOWN)
+ rc = ARITH_INVALID_TYPE;
+ else
+ rc = reduce_unary (eval, c->expr, &r);
if (rc != ARITH_OK)
break;
if (c->expr->expr_type == EXPR_CONSTANT)
rc = eval (c->expr, op2, &r);
+ else if (c->expr->expr_type == EXPR_OP && c->expr->ts.type == BT_UNKNOWN)
+ rc = ARITH_INVALID_TYPE;
else
rc = reduce_binary_ac (eval, c->expr, op2, &r);
if (c->expr->expr_type == EXPR_CONSTANT)
rc = eval (op1, c->expr, &r);
+ else if (c->expr->expr_type == EXPR_OP && c->expr->ts.type == BT_UNKNOWN)
+ rc = ARITH_INVALID_TYPE;
else
rc = reduce_binary_ca (eval, op1, c->expr, &r);
c && d;
c = gfc_constructor_next (c), d = gfc_constructor_next (d))
{
+ if ((c->expr->expr_type == EXPR_OP && c->expr->ts.type == BT_UNKNOWN)
+ || (d->expr->expr_type == EXPR_OP && d->expr->ts.type == BT_UNKNOWN))
+ rc = ARITH_INVALID_TYPE;
+ else
rc = reduce_binary (eval, c->expr, d->expr, &r);
- if (rc != ARITH_OK)
- break;
- gfc_replace_expr (c->expr, r);
+ if (rc != ARITH_OK)
+ break;
+
+ gfc_replace_expr (c->expr, r);
}
- if (c || d)
+ if (rc == ARITH_OK && (c || d))
rc = ARITH_INCOMMENSURATE;
if (rc != ARITH_OK)
else
rc = reduce_binary (eval.f3, op1, op2, &result);
+ if (rc == ARITH_INVALID_TYPE)
+ goto runtime;
/* Something went wrong. */
if (op == INTRINSIC_POWER && rc == ARITH_PROHIBIT)
arith rc;
bool did_warn = false;
+ if (src->ts.type != BT_REAL)
+ return NULL;
+
result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
mpc_set_fr (result->value.complex, src->value.real, GFC_MPC_RND_MODE);
--- /dev/null
+! { dg-do compile }
+! PR fortran/107000 - ICE in gfc_real2complex, reduce_unary, reduce_binary_*
+! Contributed by G.Steinmetz
+
+program p
+ real :: y(1)
+ complex :: x(1)
+ x = (1.0, 2.0) * [real :: -'1'] ! { dg-error "Operand of unary numeric operator" }
+ x = (1.0, 2.0) * [complex :: +'1'] ! { dg-error "Operand of unary numeric operator" }
+ x = [complex :: -'1'] * (1.0, 2.0) ! { dg-error "Operand of unary numeric operator" }
+ y = [complex :: -'1'] * 2 ! { dg-error "Operand of unary numeric operator" }
+ y = 2 * [complex :: -'1'] ! { dg-error "Operand of unary numeric operator" }
+ y = 2 * [complex :: -(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ y = [complex :: -(.true.)] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, - [real :: -'1' ] ! { dg-error "Operand of unary numeric operator" }
+ print *, - [real :: [-'1']] ! { dg-error "Operand of unary numeric operator" }
+ print *, - [real :: +(.true.) ] ! { dg-error "Operand of unary numeric operator" }
+ print *, - [real :: [+(.true.)]] ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: -'1' ] ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: (-'1')] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: -'1' ] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: (-'1')] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [integer :: -('1')] ! { dg-error "Operand of unary numeric operator" }
+ print *, [integer :: -('1')] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: 0, (-'1')] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 0, (-'1')] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: 0, -'1'] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 0, -'1'] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: 0, 1+'1'] ! { dg-error "Operands of binary numeric operator" }
+ print *, [real :: 0, 1+'1'] * 2 ! { dg-error "Operands of binary numeric operator" }
+ print *, [real :: 1, +(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, -(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ print *, 2 * [real :: 1, +(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, +(.true.)] * 2 ! { dg-error "Operand of unary numeric operator" }
+ print *, [1, 2] * [real :: 1, +(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, +(.true.)] * [1, 2] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, 2] * [real :: 1, +(.true.)] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, +(.true.)] * [real :: 1, 2] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 0, -'1'] * [real :: 1, +(+(.true.))] ! { dg-error "Operand of unary numeric operator" }
+ print *, [real :: 1, [(+(.true.))]] * [real :: 0, [(-'1')]] ! { dg-error "Operand of unary numeric operator" }
+
+ ! Legal:
+ print *, 2 * [real :: 1, [2], 3]
+ print *, [real :: 1, [2], 3] * 2
+ print *, [real :: 1, [2], 3] * [real :: 1, [2], 3]
+ print *, [real :: 1, [2], 3] * [integer :: 1, [2], 3]
+ print *, [real :: 1, [2], 3] * [1, [2], 3]
+ print *, [real :: 1, huge(2.0)] * [real :: 1, real(1.0)]
+ print *, [real :: 1, -(huge(2.0))] * [real :: 1, +(real(1))]
+end