This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch, fortran] PR31820 - add warning for implicit conversion of CASE expr
On Monday 10 May 2010 18:47:59 Daniel Franke wrote:
> Will look into it again.
Ok, here's an updated version. Instead of a single warning on promotion of the
case-expr, I added range checks for all case labels before any promotion is
done.
This program now gives:
integer(kind=1) i
i = 100_1
select case (i)
case (SUM( (/ (i, i=1, 5) /) ))
print *, "init-expr as case label"
case (SUM( (/ (i, i=1, 50) /) ))
print *, "another init-expr as case label"
case default
print *, "default!"
end select
end
$ gfortran-svn pr31820.f90
pr31820.f90:5.10:
case (SUM( (/ (i, i=1, 50) /) ))
1
Warning: Expression in CASE statement at (1) is not in the range of INTEGER(1)
For now, this is a default warning. Maybe it should be added to -Wsurprising
(implied by -Wall), together with the other CASE-related warnings, after all?!
Cheers
Daniel
Index: resolve.c
===================================================================
--- resolve.c (revision 159211)
+++ resolve.c (working copy)
@@ -6747,8 +6732,9 @@ validate_case_label_expr (gfc_expr *e, g
return FAILURE;
}
- /* Convert the case value kind to that of case expression kind, if needed.
- FIXME: Should a warning be issued? */
+ /* Convert the case value kind to that of case expression kind,
+ if needed */
+
if (e->ts.kind != case_expr->ts.kind)
gfc_convert_type_warn (e, &case_expr->ts, 2, 0);
@@ -6834,6 +6820,31 @@ resolve_select (gfc_code *code)
return;
}
+
+ /* Raise a warning if an INTEGER case value exceeds the range of
+ the case-expr. Later, all expressions will be promoted to the
+ largest kind of all case-labels. */
+
+ if (type == BT_INTEGER)
+ for (body = code->block; body; body = body->block)
+ for (cp = body->ext.case_list; cp; cp = cp->next)
+ {
+ if (cp->low
+ && gfc_check_integer_range (cp->low->value.integer,
+ case_expr->ts.kind) != ARITH_OK)
+ gfc_warning ("Expression in CASE statement at %L is "
+ "not in the range of %s", &cp->low->where,
+ gfc_typename (&case_expr->ts));
+
+ if (cp->high
+ && cp->low != cp->high
+ && gfc_check_integer_range (cp->high->value.integer,
+ case_expr->ts.kind) != ARITH_OK)
+ gfc_warning ("Expression in CASE statement at %L is "
+ "not in the range of %s", &cp->high->where,
+ gfc_typename (&case_expr->ts));
+ }
+
/* PR 19168 has a long discussion concerning a mismatch of the kinds
of the SELECT CASE expression and its CASE values. Walk the lists
of case values, and if we find a mismatch, promote case_expr to
@@ -6856,7 +6867,6 @@ resolve_select (gfc_code *code)
&& gfc_compare_expr (cp->low, cp->high, INTRINSIC_GT) > 0)
continue;
- /* FIXME: Should a warning be issued? */
if (cp->low != NULL
&& case_expr->ts.kind != gfc_kind_max(case_expr, cp->low))
gfc_convert_type_warn (case_expr, &cp->low->ts, 2, 0);
@@ -6907,8 +6917,8 @@ resolve_select (gfc_code *code)
/* Deal with single value cases and case ranges. Errors are
issued from the validation function. */
- if(validate_case_label_expr (cp->low, case_expr) != SUCCESS
- || validate_case_label_expr (cp->high, case_expr) != SUCCESS)
+ if (validate_case_label_expr (cp->low, case_expr) != SUCCESS
+ || validate_case_label_expr (cp->high, case_expr) != SUCCESS)
{
t = FAILURE;
break;
@@ -6930,7 +6940,7 @@ resolve_select (gfc_code *code)
value = cp->low->value.logical == 0 ? 2 : 1;
if (value & seen_logical)
{
- gfc_error ("constant logical value in CASE statement "
+ gfc_error ("Constant logical value in CASE statement "
"is repeated at %L",
&cp->low->where);
t = FAILURE;