re PR fortran/47659 (-Wconversion[-extra] should emit warning for constant expressions)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Sun, 21 Aug 2011 16:35:28 +0000 (16:35 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Sun, 21 Aug 2011 16:35:28 +0000 (16:35 +0000)
2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/47659
* expr.c (gfc_check_assign): Check for type conversions when the
right-hand side is a constant REAL/COMPLEX contstant the left-hand
side is also REAL/COMPLEX.  Don't warn when a narrowing conversion
for REAL does not change the value of the constant.

2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/47659
* gfortran.dg/warn_conversion_2.f90:  Also warn about conversion
of a constant resulting from simplification.
* gfortran.dg/warn_conversion_3.f90:  New test.

From-SVN: r177942

gcc/fortran/ChangeLog
gcc/fortran/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/warn_conversion_2.f90
gcc/testsuite/gfortran.dg/warn_conversion_3.f90 [new file with mode: 0644]

index 0f1f44c53fcca87448b1f561d0cfab9d4a044e89..e0ad71c34dfba2fe9994b3c811218159d6724b95 100644 (file)
@@ -1,3 +1,11 @@
+2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/47659
+       * expr.c (gfc_check_assign): Check for type conversions when the
+       right-hand side is a constant REAL/COMPLEX contstant the left-hand
+       side is also REAL/COMPLEX.  Don't warn when a narrowing conversion
+       for REAL does not change the value of the constant.
+
 2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/50130
index 549feee61c7c63a7641cf5f30e1ad4f10a675b7d..6d94369c54382f2be7b6b7f0cc9bc685425967b1 100644 (file)
@@ -3190,6 +3190,53 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform)
        }
     }
 
+  /*  Warn about type-changing conversions for REAL or COMPLEX constants.
+      If lvalue and rvalue are mixed REAL and complex, gfc_compare_types
+      will warn anyway, so there is no need to to so here.  */
+
+  if (rvalue->expr_type == EXPR_CONSTANT && lvalue->ts.type == rvalue->ts.type
+      && (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX))
+    {
+      if (lvalue->ts.kind < rvalue->ts.kind && gfc_option.gfc_warn_conversion)
+       {
+         /* As a special bonus, don't warn about REAL rvalues which are not
+            changed by the conversion if -Wconversion is specified.  */
+         if (rvalue->ts.type == BT_REAL && mpfr_number_p (rvalue->value.real))
+           {
+             /* Calculate the difference between the constant and the rounded
+                value and check it against zero.  */
+             mpfr_t rv, diff;
+             gfc_set_model_kind (lvalue->ts.kind);
+             mpfr_init (rv);
+             gfc_set_model_kind (rvalue->ts.kind);
+             mpfr_init (diff);
+             
+             mpfr_set (rv, rvalue->value.real, GFC_RND_MODE);
+             mpfr_sub (diff, rv, rvalue->value.real, GFC_RND_MODE);
+         
+             if (!mpfr_zero_p (diff))
+               gfc_warning ("Change of value in conversion from "
+                            " %s to %s at %L", gfc_typename (&rvalue->ts),
+                            gfc_typename (&lvalue->ts), &rvalue->where);
+             
+             mpfr_clear (rv);
+             mpfr_clear (diff);
+           }
+         else
+           gfc_warning ("Possible change of value in conversion from %s "
+                        "to %s at %L",gfc_typename (&rvalue->ts),
+                        gfc_typename (&lvalue->ts), &rvalue->where);
+
+       }
+      else if (gfc_option.warn_conversion_extra
+              && lvalue->ts.kind > rvalue->ts.kind)
+       {
+         gfc_warning ("Conversion from %s to %s at %L",
+                      gfc_typename (&rvalue->ts),
+                      gfc_typename (&lvalue->ts), &rvalue->where);
+       }
+    }
+
   if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
     return SUCCESS;
 
index 8a3d3f2a8a807fc563991f8acba26fcefe57111f..b0b54dece75c0a257b5ef313d31112e1c2ff1714 100644 (file)
@@ -1,3 +1,10 @@
+2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/47659
+       * gfortran.dg/warn_conversion_2.f90:  Also warn about conversion
+       of a constant resulting from simplification.
+       * gfortran.dg/warn_conversion_3.f90:  New test.
+
 2011-08-21  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/50130
index d2b4eec6049ca7df8b74f6ecb1da6cdf7d5f8ea2..d071a3c322f382212c4a2cf88613d64809206953 100644 (file)
@@ -7,5 +7,5 @@
   x = 2.0
   sqrt2 = sqrt(x)      ! { dg-warning "Conversion" }
 
-  sqrt2 = sqrt(2.0)    ! no warning; simplified to a constant and range checked
+  sqrt2 = sqrt(2.0)    ! { dg-warning "Conversion" }
 end
diff --git a/gcc/testsuite/gfortran.dg/warn_conversion_3.f90 b/gcc/testsuite/gfortran.dg/warn_conversion_3.f90
new file mode 100644 (file)
index 0000000..38d7018
--- /dev/null
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-options "-Wconversion -Wconversion-extra" }
+! PR 47659 - warning about conversions on assignment
+! Based on a test case by Thomas Henlich
+program main
+  double precision d1, d2
+  complex(8), parameter :: z = cmplx (0.5, 0.5)  ! { dg-warning "Conversion" }
+  real :: r1, r2
+  r1 = 2.3d0 ! { dg-warning "Change of value in conversion" }
+  r2 = 2.5d0 ! No warning because the value does not change
+  d1 = .13 ! { dg-warning "Conversion" }
+  d2 = .13d0
+  d1 = z     ! { dg-warning "change of value in conversion" }
+end program main