Commit 684f84de by Marek Polacek Committed by Marek Polacek

re PR c/80525 (-Wlogical-op confused by undefined integer overflow)

	PR c/80525
	* c-warn.c (unwrap_c_maybe_const): New.
	(warn_logical_operator): Call it.

	* c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore.
	* c-c++-common/Wlogical-op-2.c: New test.

From-SVN: r247786
parent 641da50a
2017-05-09 Marek Polacek <polacek@redhat.com>
PR c/80525
* c-warn.c (unwrap_c_maybe_const): New.
(warn_logical_operator): Call it.
2017-05-09 Nathan Sidwell <nathan@acm.org> 2017-05-09 Nathan Sidwell <nathan@acm.org>
* c-common.c (c_register_builtin_type): Use pushdecl lang_hook. * c-common.c (c_register_builtin_type): Use pushdecl lang_hook.
......
...@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h" #include "intl.h"
#include "asan.h" #include "asan.h"
#include "gcc-rich-location.h" #include "gcc-rich-location.h"
#include "gimplify.h"
/* Print a warning if a constant expression had overflow in folding. /* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language Invoke this function on every expression that the language
...@@ -112,6 +113,21 @@ overflow_warning (location_t loc, tree value) ...@@ -112,6 +113,21 @@ overflow_warning (location_t loc, tree value)
} }
} }
/* Helper function for walk_tree. Unwrap C_MAYBE_CONST_EXPRs in an expression
pointed to by TP. */
static tree
unwrap_c_maybe_const (tree *tp, int *walk_subtrees, void *)
{
if (TREE_CODE (*tp) == C_MAYBE_CONST_EXPR)
{
*tp = C_MAYBE_CONST_EXPR_EXPR (*tp);
/* C_MAYBE_CONST_EXPRs don't nest. */
*walk_subtrees = false;
}
return NULL_TREE;
}
/* Warn about uses of logical || / && operator in a context where it /* Warn about uses of logical || / && operator in a context where it
is likely that the bitwise equivalent was intended by the is likely that the bitwise equivalent was intended by the
programmer. We have seen an expression in which CODE is a binary programmer. We have seen an expression in which CODE is a binary
...@@ -189,11 +205,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, ...@@ -189,11 +205,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
(with OR) or trivially false (with AND). If so, do not warn. (with OR) or trivially false (with AND). If so, do not warn.
This is a common idiom for testing ranges of data types in This is a common idiom for testing ranges of data types in
portable code. */ portable code. */
op_left = unshare_expr (op_left);
walk_tree_without_duplicates (&op_left, unwrap_c_maybe_const, NULL);
lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p); lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
if (!lhs) if (!lhs)
return; return;
if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
/* If this is an OR operation, invert both sides; now, the result /* If this is an OR operation, invert both sides; now, the result
should be always false to get a warning. */ should be always false to get a warning. */
...@@ -204,11 +220,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, ...@@ -204,11 +220,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
if (tem && integer_zerop (tem)) if (tem && integer_zerop (tem))
return; return;
op_right = unshare_expr (op_right);
walk_tree_without_duplicates (&op_right, unwrap_c_maybe_const, NULL);
rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p); rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
if (!rhs) if (!rhs)
return; return;
if (TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
/* If this is an OR operation, invert both sides; now, the result /* If this is an OR operation, invert both sides; now, the result
should be always false to get a warning. */ should be always false to get a warning. */
......
2017-05-09 Marek Polacek <polacek@redhat.com>
PR c/80525
* c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore.
* c-c++-common/Wlogical-op-2.c: New test.
2017-05-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> 2017-05-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* gcc.dg/tree-ssa/cunroll-13.c: Use __INT32_TYPE__ for * gcc.dg/tree-ssa/cunroll-13.c: Use __INT32_TYPE__ for
......
/* PR c/63357 */ /* PR c/63357 */
/* { dg-do compile } */ /* { dg-do compile } */
/* For -fwrapv see PR80525, xfailing the subtest isn't possible as it passes /* { dg-options "-Wlogical-op" } */
with the C++ FE which doesn't have maybe_const_expr. */
/* { dg-options "-fwrapv -Wlogical-op" } */
#ifndef __cplusplus #ifndef __cplusplus
# define bool _Bool # define bool _Bool
......
/* PR c/80525 */
/* { dg-do compile } */
/* { dg-options "-Wlogical-op" } */
int
fn (int a, int b)
{
if ((a + 1) && (a + 1)) /* { dg-warning "logical .and. of equal expressions" } */
return a;
if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */
return b;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment