Am 22.08.2012 11:18, schrieb Tobias Burnus:
Regarding -Wcompare-real, I wonder whether it makes sense to either ignore comparisions against zero or to put them into a different flag (-Wcompare-real-zero);
Here is a patch to not warn for comparisons against zero. Regression-tested, also tested with make info and make dvi. OK for trunk? Thomas 012-08-22 Thomas König <tkoe...@gcc.gnu.org> PR fortran/54298 * invoke.texi: Document that -Wcompare-reals does not warn for comparison against zero. * resolve.c (is_real_zero): New function. (is_complex_zero): New function. (resolve_operator): If the comparison is against real or complex zero, don't warn about equality/inequality comparisions. Document how to suppress the warning in the error message. 2012-08-22 Thomas König <tkoe...@gcc.gnu.org> PR fortran/54298 * gfortran.dg/compare_real_2.f90: New test.
Index: invoke.texi =================================================================== --- invoke.texi (Revision 190541) +++ invoke.texi (Arbeitskopie) @@ -939,7 +939,8 @@ allocatable variable; this includes scalars and de @item -Wcompare-reals @opindex @code{Wcompare-reals} Warn when comparing real or complex types for equality or inequality. -Enabled by @option{-Wall}. +Comparisons against zero are not warned about. Enabled by +@option{-Wall}. @item -Wtarget-lifetime @opindex @code{Wtargt-lifetime} Index: resolve.c =================================================================== --- resolve.c (Revision 190541) +++ resolve.c (Arbeitskopie) @@ -3876,7 +3876,27 @@ compare_shapes (gfc_expr *op1, gfc_expr *op2) return t; } +/* Check if an expr is a zero REAL constant. */ +static bool +is_real_zero (gfc_expr *e) +{ + return e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT + && mpfr_sgn (e->value.real) == 0; + +} + +/* Check if an expr is a zero COMPLEX constant. */ + +static bool +is_complex_zero (gfc_expr *e) +{ + return e->ts.type == BT_COMPLEX && e->expr_type == EXPR_CONSTANT + && mpfr_sgn (mpc_realref (e->value.complex)) == 0 + && mpfr_sgn (mpc_imagref (e->value.complex)) == 0; + +} + /* Resolve an operator expression node. This can involve replacing the operation with a user defined function call. */ @@ -4047,11 +4067,16 @@ resolve_operator (gfc_expr *e) { const char *msg; + /* Comparisons against zero are usually legitimate, so let's not warn. */ + if (is_real_zero (op1) || is_real_zero (op2) + || is_complex_zero (op1) || is_complex_zero (op2)) + break; + if (op == INTRINSIC_EQ || op == INTRINSIC_EQ_OS) - msg = "Equality comparison for %s at %L"; + msg = "Equality comparison for %s at %L [use -Wno-compare-reals to suppress]"; else - msg = "Inequality comparison for %s at %L"; - + msg = "Inequality comparison for %s at %L [use -Wno-compare-reals to suppress]"; + gfc_warning (msg, gfc_typename (&op1->ts), &op1->where); } }
! { dg-do compile } ! { dg-options "-Wcompare-reals" } program main real :: a complex :: c read (*,*) a read (*,*) c if (a .eq. 0.) print *,"foo" if (0. == a) print *,"foo" if (a .eq. 0) print *,"foo" if (0 == a) print *,"foo" if (a .ne. 0.0) print *,"foo" if (0.0 /= a) print *,"foo" if (a .ne. 0) print *,"foo" if (0 /= a) print *,"foo" if (c .eq. (0., 0.)) print *,"foo" if ((0., 0.) == a) print *,"foo" if (c .ne. (0., 0.)) print *,"foo" if ((0., 2.11) /= c) print *,"foo" ! { dg-warning "Inequality comparison for COMPLEX" } if ((2.11, 0.) /= c) print *,"foo" ! { dg-warning "Inequality comparison for COMPLEX" } end program main