diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2011-08-21 16:35:28 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2011-08-21 16:35:28 +0000 |
commit | 6cd1d48e9e4dd7ceb80a6dff6f113d5020c5d9d6 (patch) | |
tree | 1f4e191a57eb5e520ee4afb6a3a660851d2d1f2a /gcc | |
parent | 38acd2910a3a23bc48131ceef153ac52f23b8ed6 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/expr.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/warn_conversion_2.f90 | 2 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/warn_conversion_3.f90 | 14 |
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 |