diff options
Diffstat (limited to 'gcc/fortran/arith.cc')
-rw-r--r-- | gcc/fortran/arith.cc | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index d57059a..086b1f8 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -118,6 +118,9 @@ gfc_arith_error (arith code) 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"); @@ -1268,7 +1271,10 @@ reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op, 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; @@ -1309,6 +1315,8 @@ reduce_binary_ac (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), 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); @@ -1361,6 +1369,8 @@ reduce_binary_ca (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), 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); @@ -1420,14 +1430,19 @@ reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), 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) @@ -1638,6 +1653,8 @@ eval_intrinsic (gfc_intrinsic_op op, 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) @@ -2238,6 +2255,9 @@ gfc_real2complex (gfc_expr *src, int kind) 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); |