Commit 33169a22 by Daniel Franke Committed by Daniel Franke

re PR fortran/44359 (-Wall / -Wconversion: Too verbose warning for DATA BOZ conversions)

gcc/fortran/:
2010-06-09  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/44359
	* intrinsic.c (gfc_convert_type_warn): Further improve -Wconversion.

gcc/testsuite/:
2010-06-09  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/44359
	* gfortran.dg/warn_conversion.f90: Removed check for redundant
	warning.
	* gfortran.dg/warn_conversion_2.f90: Use non-constant expression to
	check for warning.

From-SVN: r160505
parent b51789fe
2010-06-09 Daniel Franke <franke.daniel@gmail.com>
PR fortran/44359
* intrinsic.c (gfc_convert_type_warn): Further improve -Wconversion.
2010-06-09 Janus Weil <janus@gcc.gnu.org> 2010-06-09 Janus Weil <janus@gcc.gnu.org>
PR fortran/44430 PR fortran/44430
......
...@@ -4022,58 +4022,67 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag) ...@@ -4022,58 +4022,67 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
} }
else if (wflag) else if (wflag)
{ {
/* Two modes of warning: if (gfc_option.flag_range_check
- gfc_option.warn_conversion tries to be more intelligent && expr->expr_type == EXPR_CONSTANT
about the warnings raised and omits those where smaller && from_ts.type == ts->type)
kinds are promoted to larger ones without change in the {
value /* Do nothing. Constants of the same type are range-checked
- gfc_option.warn_conversion_extra does not take the kinds elsewhere. If a value too large for the target type is
into account and also warns for coversions like assigned, an error is generated. Not checking here avoids
REAL(4) -> REAL(8) duplications of warnings/errors.
If range checking was disabled, but -Wconversion enabled,
NOTE: Possible enhancement for warn_conversion a non range checked warning is generated below. */
If converting from a smaller to a larger kind, check if the }
value is constant and if yes, whether the value still fits else if (from_ts.type == BT_LOGICAL || ts->type == BT_LOGICAL)
in the smaller kind. If yes, omit the warning. {
*/ /* Do nothing. This block exists only to simplify the other
else-if expressions.
/* If the types are the same (but not LOGICAL), and if from-kind LOGICAL <> LOGICAL no warning, independent of kind values
is larger than to-kind, this may indicate a loss of precision. LOGICAL <> INTEGER extension, warned elsewhere
The same holds for conversions from REAL to COMPLEX. */ LOGICAL <> REAL invalid, error generated elsewhere
if (((from_ts.type == ts->type && from_ts.type != BT_LOGICAL) LOGICAL <> COMPLEX invalid, error generated elsewhere */
&& ((gfc_option.warn_conversion && from_ts.kind > ts->kind) }
|| gfc_option.warn_conversion_extra)) else if (from_ts.type == ts->type
|| ((from_ts.type == BT_REAL && ts->type == BT_COMPLEX) || (from_ts.type == BT_INTEGER && ts->type == BT_REAL)
&& ((gfc_option.warn_conversion && from_ts.kind > ts->kind) || (from_ts.type == BT_INTEGER && ts->type == BT_COMPLEX)
|| gfc_option.warn_conversion_extra))) || (from_ts.type == BT_REAL && ts->type == BT_COMPLEX))
gfc_warning_now ("Possible change of value in conversion " {
"from %s to %s at %L", gfc_typename (&from_ts), /* Larger kinds can hold values of smaller kinds without problems.
gfc_typename (ts), &expr->where); Hence, only warn if target kind is smaller than the source
kind - or if -Wconversion-extra is specified. */
/* If INTEGER is converted to REAL/COMPLEX, this is generally ok if if (gfc_option.warn_conversion_extra)
the kind of the INTEGER value is less or equal to the kind of the gfc_warning_now ("Conversion from %s to %s at %L",
REAL/COMPLEX one. Otherwise the value may not fit. gfc_typename (&from_ts), gfc_typename (ts),
Assignment of an overly large integer constant also generates &expr->where);
an overflow error with range checking. */ else if (gfc_option.warn_conversion
else if (from_ts.type == BT_INTEGER && from_ts.kind > ts->kind)
&& (ts->type == BT_REAL || ts->type == BT_COMPLEX) gfc_warning_now ("Possible change of value in conversion "
&& ((gfc_option.warn_conversion && from_ts.kind > ts->kind) "from %s to %s at %L", gfc_typename (&from_ts),
|| gfc_option.warn_conversion_extra)) gfc_typename (ts), &expr->where);
gfc_warning_now ("Possible change of value in conversion " }
"from %s to %s at %L", gfc_typename (&from_ts), else if ((from_ts.type == BT_REAL && ts->type == BT_INTEGER)
gfc_typename (ts), &expr->where); || (from_ts.type == BT_COMPLEX && ts->type == BT_INTEGER)
|| (from_ts.type == BT_COMPLEX && ts->type == BT_REAL))
/* If REAL/COMPLEX is converted to INTEGER, or COMPLEX is converted {
to REAL we almost certainly have a loss of digits, regardless of /* Conversion from REAL/COMPLEX to INTEGER or COMPLEX to REAL
the respective kinds. */ usually comes with a loss of information, regardless of kinds. */
else if ((((from_ts.type == BT_REAL || from_ts.type == BT_COMPLEX) if (gfc_option.warn_conversion_extra
&& ts->type == BT_INTEGER) || gfc_option.warn_conversion)
|| (from_ts.type == BT_COMPLEX && ts->type == BT_REAL)) gfc_warning_now ("Possible change of value in conversion "
&& (gfc_option.warn_conversion "from %s to %s at %L", gfc_typename (&from_ts),
|| gfc_option.warn_conversion_extra)) gfc_typename (ts), &expr->where);
gfc_warning_now ("Possible change of value in conversion from " }
"%s to %s at %L", gfc_typename (&from_ts), else if (from_ts.type == BT_HOLLERITH || ts->type == BT_HOLLERITH)
gfc_typename (ts), &expr->where); {
/* If HOLLERITH is involved, all bets are off. */
if (gfc_option.warn_conversion_extra
|| gfc_option.warn_conversion)
gfc_warning_now ("Conversion from %s to %s at %L",
gfc_typename (&from_ts), gfc_typename (ts),
&expr->where);
}
else
gcc_unreachable ();
} }
/* Insert a pre-resolved function call to the right function. */ /* Insert a pre-resolved function call to the right function. */
......
2010-06-09 Daniel Franke <franke.daniel@gmail.com>
PR fortran/44359
* gfortran.dg/warn_conversion.f90: Removed check for redundant
warning.
* gfortran.dg/warn_conversion_2.f90: Use non-constant expression to
check for warning.
2010-06-09 Steven G. Kargl <kargl@gcc.gnu.org> 2010-06-09 Steven G. Kargl <kargl@gcc.gnu.org>
* gfortran.dg/data_namelist_conflict.f90: New test. * gfortran.dg/data_namelist_conflict.f90: New test.
......
...@@ -18,7 +18,6 @@ SUBROUTINE pr27866c4 ...@@ -18,7 +18,6 @@ SUBROUTINE pr27866c4
integer(kind=4) :: i4 integer(kind=4) :: i4
i4 = 2.3 ! { dg-warning "conversion" } i4 = 2.3 ! { dg-warning "conversion" }
i1 = 500 ! { dg-error "overflow" } i1 = 500 ! { dg-error "overflow" }
! { dg-warning "conversion" "" { target *-*-* } 20 }
a = 2**26-1 ! assignment INTEGER(4) to REAL(4) - no warning a = 2**26-1 ! assignment INTEGER(4) to REAL(4) - no warning
b = 1d999 ! { dg-error "overflow" } b = 1d999 ! { dg-error "overflow" }
......
...@@ -2,5 +2,10 @@ ...@@ -2,5 +2,10 @@
! { dg-options "-Wconversion-extra" } ! { dg-options "-Wconversion-extra" }
real(8) :: sqrt2 real(8) :: sqrt2
sqrt2 = sqrt(2.0) ! { dg-warning "conversion" } real x
x = 2.0
sqrt2 = sqrt(x) ! { dg-warning "Conversion" }
sqrt2 = sqrt(2.0) ! no warning; simplified to a constant and range checked
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment