aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2011-08-21 16:35:28 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2011-08-21 16:35:28 +0000
commit6cd1d48e9e4dd7ceb80a6dff6f113d5020c5d9d6 (patch)
tree1f4e191a57eb5e520ee4afb6a3a660851d2d1f2a /gcc
parent38acd2910a3a23bc48131ceef153ac52f23b8ed6 (diff)
downloadgcc-6cd1d48e9e4dd7ceb80a6dff6f113d5020c5d9d6.zip
gcc-6cd1d48e9e4dd7ceb80a6dff6f113d5020c5d9d6.tar.gz
gcc-6cd1d48e9e4dd7ceb80a6dff6f113d5020c5d9d6.tar.bz2
re PR fortran/47659 (-Wconversion[-extra] should emit warning for constant expressions)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/expr.c47
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gfortran.dg/warn_conversion_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/warn_conversion_3.f9014
5 files changed, 77 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 0f1f44c..e0ad71c 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,13 @@
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
* resolve.c (resolve_array_ref): Don't calculate upper bound
if the stride is zero.
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 549feee..6d94369 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a3d3f2..b0b54de 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
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
* gfortran.dg/zero_stride_1.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/warn_conversion_2.f90 b/gcc/testsuite/gfortran.dg/warn_conversion_2.f90
index d2b4eec..d071a3c 100644
--- a/gcc/testsuite/gfortran.dg/warn_conversion_2.f90
+++ b/gcc/testsuite/gfortran.dg/warn_conversion_2.f90
@@ -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
index 0000000..38d7018
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_conversion_3.f90
@@ -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