aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 3c28d45..44236e5 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5084,6 +5084,28 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
goto call;
}
+ if (code->expr->ts.type == BT_CHARACTER
+ && gfc_option.warn_character_truncation)
+ {
+ int llen = 0, rlen = 0;
+ gfc_symbol *sym;
+ sym = code->expr->symtree->n.sym;
+ if (sym->ts.cl->length->expr_type == EXPR_CONSTANT)
+ llen = mpz_get_si (sym->ts.cl->length->value.integer);
+
+ if (code->expr2->expr_type == EXPR_CONSTANT)
+ rlen = code->expr2->value.character.length;
+
+ else if (code->expr2->ts.cl != NULL
+ && code->expr2->ts.cl->length != NULL
+ && code->expr2->ts.cl->length->expr_type == EXPR_CONSTANT)
+ rlen = mpz_get_si (code->expr2->ts.cl->length->value.integer);
+
+ if (rlen && llen && rlen > llen)
+ gfc_warning_now ("rhs of CHARACTER assignment at %L will "
+ "be truncated (%d/%d)", &code->loc, rlen, llen);
+ }
+
if (gfc_pure (NULL))
{
if (gfc_impure_variable (code->expr->symtree->n.sym))
@@ -6435,17 +6457,47 @@ traverse_data_list (gfc_data_variable * var, locus * where)
{
mpz_t trip;
iterator_stack frame;
- gfc_expr *e;
+ gfc_expr *e, *start, *end, *step;
+ try retval = SUCCESS;
mpz_init (frame.value);
- mpz_init_set (trip, var->iter.end->value.integer);
- mpz_sub (trip, trip, var->iter.start->value.integer);
- mpz_add (trip, trip, var->iter.step->value.integer);
+ start = gfc_copy_expr (var->iter.start);
+ end = gfc_copy_expr (var->iter.end);
+ step = gfc_copy_expr (var->iter.step);
+
+ if (gfc_simplify_expr (start, 1) == FAILURE
+ || start->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("iterator start at %L does not simplify",
+ &start->where);
+ retval = FAILURE;
+ goto cleanup;
+ }
+ if (gfc_simplify_expr (end, 1) == FAILURE
+ || end->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("iterator end at %L does not simplify",
+ &end->where);
+ retval = FAILURE;
+ goto cleanup;
+ }
+ if (gfc_simplify_expr (step, 1) == FAILURE
+ || step->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("iterator step at %L does not simplify",
+ &step->where);
+ retval = FAILURE;
+ goto cleanup;
+ }
+
+ mpz_init_set (trip, end->value.integer);
+ mpz_sub (trip, trip, start->value.integer);
+ mpz_add (trip, trip, step->value.integer);
- mpz_div (trip, trip, var->iter.step->value.integer);
+ mpz_div (trip, trip, step->value.integer);
- mpz_set (frame.value, var->iter.start->value.integer);
+ mpz_set (frame.value, start->value.integer);
frame.prev = iter_stack;
frame.variable = var->iter.var->symtree;
@@ -6456,26 +6508,34 @@ traverse_data_list (gfc_data_variable * var, locus * where)
if (traverse_data_var (var->list, where) == FAILURE)
{
mpz_clear (trip);
- return FAILURE;
+ retval = FAILURE;
+ goto cleanup;
}
e = gfc_copy_expr (var->expr);
if (gfc_simplify_expr (e, 1) == FAILURE)
- {
- gfc_free_expr (e);
- return FAILURE;
- }
+ {
+ gfc_free_expr (e);
+ mpz_clear (trip);
+ retval = FAILURE;
+ goto cleanup;
+ }
- mpz_add (frame.value, frame.value, var->iter.step->value.integer);
+ mpz_add (frame.value, frame.value, step->value.integer);
mpz_sub_ui (trip, trip, 1);
}
mpz_clear (trip);
+cleanup:
mpz_clear (frame.value);
+ gfc_free_expr (start);
+ gfc_free_expr (end);
+ gfc_free_expr (step);
+
iter_stack = frame.prev;
- return SUCCESS;
+ return retval;
}
@@ -6520,11 +6580,6 @@ resolve_data_variables (gfc_data_variable * d)
if (gfc_resolve_iterator (&d->iter, false) == FAILURE)
return FAILURE;
- if (d->iter.start->expr_type != EXPR_CONSTANT
- || d->iter.end->expr_type != EXPR_CONSTANT
- || d->iter.step->expr_type != EXPR_CONSTANT)
- gfc_internal_error ("resolve_data_variables(): Bad iterator");
-
if (resolve_data_variables (d->list) == FAILURE)
return FAILURE;
}