aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Franke <franke.daniel@gmail.com>2010-05-10 17:10:53 +0000
committerDaniel Franke <franke.daniel@gmail.com>2010-05-10 17:10:53 +0000
commit97660c37097f0f3ffec4524c146d61c6ddcf5b19 (patch)
tree2241c99c74552e029f3b44cbfe1915704c74deba
parent4cb2a1499f52a4af76da397adc6864ca4bc9d577 (diff)
gcc/fortran/:
2010-05-10 Daniel Franke <franke.daniel@gmail.com> PR fortran/27866 PR fortran/35003 PR fortran/42809 * intrinsic.c (gfc_convert_type_warn): Be more discriminative about conversion warnings. gcc/testsuite/: 2010-05-08 Daniel Franke <franke.daniel@gmail.com> PR fortran/27866 PR fortran/35003 PR fortran/42809 * gfortran.dg/array_constructor_type_17.f03: Updated match string. * gfortran.dg/warn_conversion.f90: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@159238 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/intrinsic.c36
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_type_17.f032
-rw-r--r--gcc/testsuite/gfortran.dg/warn_conversion.f9062
5 files changed, 113 insertions, 3 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index d168a3b44aa..af70b8c67a6 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,11 @@
+2010-05-10 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/27866
+ PR fortran/35003
+ PR fortran/42809
+ * intrinsic.c (gfc_convert_type_warn): Be more dicsriminative
+ about conversion warnings.
+
2010-05-10 Janus Weil <janus@gcc.gnu.org>
PR fortran/44044
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index e8041eb9b9a..07867541be0 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -4016,8 +4016,40 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
gfc_warning_now ("Extension: Conversion from %s to %s at %L",
gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
else if (wflag && gfc_option.warn_conversion)
- gfc_warning_now ("Conversion from %s to %s at %L",
- gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+ {
+ /* If the types are the same (but not LOGICAL), and if from-kind
+ is larger than to-kind, this may indicate a loss of precision.
+ The same holds for conversions from REAL to COMPLEX. */
+ if (((from_ts.type == ts->type && from_ts.type != BT_LOGICAL)
+ && from_ts.kind > ts->kind)
+ || ((from_ts.type == BT_REAL && ts->type == BT_COMPLEX)
+ && from_ts.kind > ts->kind))
+ gfc_warning_now ("Possible loss of precision in conversion "
+ "from %s to %s at %L", gfc_typename (&from_ts),
+ gfc_typename (ts), &expr->where);
+
+ /* If INTEGER is converted to REAL/COMPLEX, this is generally ok if
+ the kind of the INTEGER value is less or equal to the kind of the
+ REAL/COMPLEX one. Otherwise the value may not fit.
+ Assignment of an overly large integer constant also generates
+ an overflow error with range checking. */
+ else if (from_ts.type == BT_INTEGER
+ && (ts->type == BT_REAL || ts->type == BT_COMPLEX)
+ && from_ts.kind > ts->kind)
+ gfc_warning_now ("Possible loss of digits in conversion "
+ "from %s to %s at %L", gfc_typename (&from_ts),
+ gfc_typename (ts), &expr->where);
+
+ /* If REAL/COMPLEX is converted to INTEGER, or COMPLEX is converted
+ to REAL we almost certainly have a loss of digits, regardless of
+ the respective kinds. */
+ else if (((from_ts.type == BT_REAL || from_ts.type == BT_COMPLEX)
+ && ts->type == BT_INTEGER)
+ || (from_ts.type == BT_COMPLEX && ts->type == BT_REAL))
+ gfc_warning_now ("Likely loss of digits in conversion from"
+ "%s to %s at %L", gfc_typename (&from_ts),
+ gfc_typename (ts), &expr->where);
+ }
/* Insert a pre-resolved function call to the right function. */
old_where = expr->where;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index de216a3876f..f54d9c4a898 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2010-05-08 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/27866
+ PR fortran/35003
+ PR fortran/42809
+ * gfortran.dg/array_constructor_type_17.f03: Updated match string.
+ * gfortran.dg/warn_conversion.f90: New.
+
2010-05-10 Michael Matz <matz@suse.de>
* gcc.dg/vect/fast-math-vect-reduc-8.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_type_17.f03 b/gcc/testsuite/gfortran.dg/array_constructor_type_17.f03
index 365d43e3f75..f8f15f9eba1 100644
--- a/gcc/testsuite/gfortran.dg/array_constructor_type_17.f03
+++ b/gcc/testsuite/gfortran.dg/array_constructor_type_17.f03
@@ -8,5 +8,5 @@ PROGRAM test
IMPLICIT NONE
INTEGER(KIND=4) :: arr(1)
- arr = (/ INTEGER(KIND=4) :: HUGE(0_8) /) ! { dg-warning "Conversion from" }
+ arr = (/ INTEGER(KIND=4) :: HUGE(0_8) /) ! { dg-warning "conversion from" }
END PROGRAM test
diff --git a/gcc/testsuite/gfortran.dg/warn_conversion.f90 b/gcc/testsuite/gfortran.dg/warn_conversion.f90
new file mode 100644
index 00000000000..f658b655cae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_conversion.f90
@@ -0,0 +1,62 @@
+! { dg-do "compile" }
+! { dg-options "-Wconversion" }
+
+!
+! PR fortran/27866 -improve -Wconversion
+!
+SUBROUTINE pr27866
+ double precision :: d
+ real :: r
+ d = 4d99
+ r = d ! { dg-warning "conversion" }
+END SUBROUTINE
+
+SUBROUTINE pr27866c4
+ real(kind=4) :: a
+ real(kind=8) :: b
+ integer(kind=1) :: i1
+ integer(kind=4) :: i4
+ i4 = 2.3 ! { dg-warning "conversion" }
+ i1 = 500 ! { dg-error "overflow" }
+ ! { dg-warning "conversion" "" { target *-*-* } 20 }
+ a = 2**26-1 ! assignment INTEGER(4) to REAL(4) - no warning
+ b = 1d999 ! { dg-error "overflow" }
+
+ a = i4 ! assignment INTEGER(4) to REAL(4) - no warning
+ b = i4 ! assignment INTEGER(4) to REAL(8) - no warning
+ i1 = i4 ! { dg-warning "conversion" }
+ a = b ! { dg-warning "conversion" }
+END SUBROUTINE
+
+
+!
+! PR fortran/35003 - spurious warning with -Wconversion
+! Contributed by Brian Barnes <bcbarnes AT gmail DOT com>
+!
+SUBROUTINE pr35003
+ IMPLICIT NONE
+ integer(8) :: i, n
+ n = 1_8
+
+ do i = 1_8,n
+ enddo
+END SUBROUTINE
+
+
+!
+! PR fortran/42809 - Too much noise with -Wconversion
+! Contributed by Harald Anlauf <anlauf AT gmx DOT de>
+!
+SUBROUTINE pr42809
+ implicit none
+ integer, parameter :: sp = kind (1.0)
+ integer, parameter :: dp = kind (1.d0)
+ real(sp) :: s
+ real(dp) :: d
+ complex(dp) :: z
+
+ s = 0 ! assignment INTEGER(4) to REAL(4) - no warning
+ d = s ! assignment REAL((8)) to REAL(4) - no warning
+ z = (0, 1) ! conversion INTEGER(4) to REAL(4),
+ ! assignment COMPLEX(4) to COMPLEX(8) - no warning
+END SUBROUTINE