Index: resolve.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fortran/resolve.c,v retrieving revision 1.24 diff -u -b -u -b -B -r1.24 resolve.c --- resolve.c 15 Dec 2004 03:56:05 -0000 1.24 +++ resolve.c 1 Jan 2005 21:11:46 -0000 @@ -2614,7 +2579,7 @@ /* Count this merge. */ nmerges++; - /* Cut the list in two pieces by steppin INSIZE places + /* Cut the list in two pieces by stepping INSIZE places forward in the list, starting from P. */ psize = 0; q = p; @@ -2711,32 +2676,39 @@ } -/* Check to see if an expression is suitable for use in a CASE - statement. Makes sure that all case expressions are scalar - constants of the same type/kind. Return FAILURE if anything - is wrong. */ +/* Check to see if an expression is suitable for use in a CASE statement. + Makes sure that all case expressions are scalar constants of the same + type. Return FAILURE if anything is wrong. */ static try validate_case_label_expr (gfc_expr * e, gfc_expr * case_expr) { - gfc_typespec case_ts = case_expr->ts; if (e == NULL) return SUCCESS; - if (e->ts.type != case_ts.type) + if (e->ts.type != case_expr->ts.type) { gfc_error ("Expression in CASE statement at %L must be of type %s", - &e->where, gfc_basic_typename (case_ts.type)); + &e->where, gfc_basic_typename (case_expr->ts.type)); return FAILURE; } - if (e->ts.kind != case_ts.kind) + /* C805 (R808) For a given case-construct, each case-value shall be of + the same type as case-expr. For character type, length differences + are allowed, but the kind type parameters shall be the same. */ + + if (case_expr->ts.type == BT_CHARACTER && e->ts.kind != case_expr->ts.kind) { gfc_error("Expression in CASE statement at %L must be kind %d", - &e->where, case_ts.kind); + &e->where, case_expr->ts.kind); return FAILURE; } + /* Convert the case value kind to that of case expression kind, if needed. + FIXME: Should a warning be issued? */ + if (e->ts.kind != case_expr->ts.kind) + gfc_convert_type_warn (e, &case_expr->ts, 2, 0); + if (e->rank != 0) { gfc_error ("Expression in CASE statement at %L must be scalar", @@ -2819,6 +2791,40 @@ return; } + /* 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 + the appropriate kind. */ + + if (type == BT_LOGICAL || type == BT_INTEGER) + { + for (body = code->block; body; body = body->block) + { + /* Walk the case label list. */ + for (cp = body->ext.case_list; cp; cp = cp->next) + { + /* Intercept the DEFAULT case. It does not have a kind. */ + if (cp->low == NULL && cp->high == NULL) + continue; + + /* Unreachable case ranges are discarded, so ignore. */ + if (cp->low != NULL && cp->high != NULL + && cp->low != cp->high + && gfc_compare_expr (cp->low, cp->high) > 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); + + if (cp->high != NULL + && case_expr->ts.kind != gfc_kind_max(case_expr, cp->high)) + gfc_convert_type_warn (case_expr, &cp->high->ts, 2, 0); + } + } + } + /* Assume there is no DEFAULT case. */ default_case = NULL; head = tail = NULL;