From patchwork Sun Aug 14 15:36:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [fortran] PR 46659 - extend conversion warnings to assignments X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 109960 Message-Id: <4E47EB84.6080006@netcologne.de> To: "fortran@gcc.gnu.org" , gcc-patches Date: Sun, 14 Aug 2011 17:36:36 +0200 From: Thomas Koenig List-Id: Hello world, the attached patch extends conversion warnings to assignments. OK for trunk? Thomas 011-08-14 Thomas Koenig PR fortran/46659 * expr.c (gfc_check_assign): Check for type conversions when the right-hand side is a constant REAL cor COMPLEX contstant the left-hand side is also REAL or COMPLEX. Don't warn when a narrowing conversion does not change the value of the constant. 2011-08-14 Thomas Koenig PR fortran/46659 * gfortran.dg/warn_conversion_2.f90: Also warn about conversion of a constant resulting from simplification. * gfortran.dg/warn_conversion_3.f90: New test. ! { 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 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 end program main Index: fortran/expr.c =================================================================== --- fortran/expr.c (Revision 177746) +++ fortran/expr.c (Arbeitskopie) @@ -3190,6 +3190,53 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rval } } + /* If lvalue is REAL and rvalue is a REAL constant with different, + warn about possible errors the user may have done during conversion. */ + + if (rvalue->expr_type == EXPR_CONSTANT + && (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX) + && (rvalue->ts.type == BT_REAL || rvalue->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: testsuite/gfortran.dg/warn_conversion_2.f90 =================================================================== --- testsuite/gfortran.dg/warn_conversion_2.f90 (Revision 177746) +++ testsuite/gfortran.dg/warn_conversion_2.f90 (Arbeitskopie) @@ -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