OSDN Git Service

gcc/fortran/:
authordfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 May 2010 17:10:53 +0000 (17:10 +0000)
committerdfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 May 2010 17:10:53 +0000 (17:10 +0000)
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159238 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/array_constructor_type_17.f03
gcc/testsuite/gfortran.dg/warn_conversion.f90 [new file with mode: 0644]

index d168a3b..af70b8c 100644 (file)
@@ -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
 2010-05-10  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/44044
index e8041eb..0786754 100644 (file)
@@ -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 ("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;
 
   /* Insert a pre-resolved function call to the right function.  */
   old_where = expr->where;
index de216a3..f54d9c4 100644 (file)
@@ -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.
 2010-05-10  Michael Matz  <matz@suse.de>
 
        * gcc.dg/vect/fast-math-vect-reduc-8.c: New test.
index 365d43e..f8f15f9 100644 (file)
@@ -8,5 +8,5 @@ PROGRAM test
   IMPLICIT NONE
 
   INTEGER(KIND=4) :: arr(1)
   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
 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 (file)
index 0000000..f658b65
--- /dev/null
@@ -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