===================================================================
@@ -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}
===================================================================
@@ -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);
}
}