From 485f6b9ca432a3d768a41981cc798442fb81abac Mon Sep 17 00:00:00 2001 From: mpolacek Date: Fri, 24 Apr 2015 12:10:52 +0000 Subject: [PATCH] PR c/63357 * c-common.c (warn_logical_operator): Warn if the operands have the same expressions. * doc/invoke.texi: Update description of -Wlogical-op. * c-c++-common/Wlogical-op-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222408 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 3 + gcc/c-family/ChangeLog | 4 ++ gcc/c-family/c-common.c | 39 +++++++---- gcc/doc/invoke.texi | 7 +- gcc/testsuite/ChangeLog | 3 + gcc/testsuite/c-c++-common/Wlogical-op-1.c | 109 +++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wlogical-op-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bb36799a17..d489b4a7d85 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,9 @@ PR c/61534 * input.h (from_macro_expansion_at): Define. + PR c/63357 + * doc/invoke.texi: Update description of -Wlogical-op. + 2015-04-24 Thomas Preud'homme * config/arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_DECL_LOCAL): fix diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 718aa2ad0a0..1eb27cd4bce 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -4,6 +4,10 @@ * c-common.c (c_fully_fold_internal): Use OPT_Wshift_count_negative and OPT_Wshift_count_overflow. + PR c/63357 + * c-common.c (warn_logical_operator): Warn if the operands have the + same expressions. + 2015-04-24 Marek Polacek PR c/61534 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index b8e141eb42f..9797e1701d3 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1781,22 +1781,35 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, return; /* If both expressions have the same operand, if we can merge the - ranges, and if the range test is always false, then warn. */ + ranges, ... */ if (operand_equal_p (lhs, rhs, 0) && merge_ranges (&in_p, &low, &high, in0_p, low0, high0, - in1_p, low1, high1) - && 0 != (tem = build_range_check (UNKNOWN_LOCATION, - type, lhs, in_p, low, high)) - && integer_zerop (tem)) + in1_p, low1, high1)) { - if (or_op) - warning_at (location, OPT_Wlogical_op, - "logical % " - "of collectively exhaustive tests is always true"); - else - warning_at (location, OPT_Wlogical_op, - "logical % " - "of mutually exclusive tests is always false"); + tem = build_range_check (UNKNOWN_LOCATION, type, lhs, in_p, low, high); + /* ... and if the range test is always false, then warn. */ + if (tem && integer_zerop (tem)) + { + if (or_op) + warning_at (location, OPT_Wlogical_op, + "logical % of collectively exhaustive tests is " + "always true"); + else + warning_at (location, OPT_Wlogical_op, + "logical % of mutually exclusive tests is " + "always false"); + } + /* Or warn if the operands have exactly the same range, e.g. + A > 0 && A > 0. */ + else if (low0 == low1 && high0 == high1) + { + if (or_op) + warning_at (location, OPT_Wlogical_op, + "logical % of equal expressions"); + else + warning_at (location, OPT_Wlogical_op, + "logical % of equal expressions"); + } } } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a939ff74670..52e2e2218c1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -4936,7 +4936,12 @@ programmer intended to use @code{strcmp}. This warning is enabled by @opindex Wno-logical-op Warn about suspicious uses of logical operators in expressions. This includes using logical operators in contexts where a -bit-wise operator is likely to be expected. +bit-wise operator is likely to be expected. Also warns when +the operands of a logical operator are the same: +@smallexample +extern int a; +if (a < 0 && a < 0) @{ @dots{} @} +@end smallexample @item -Wlogical-not-parentheses @opindex Wlogical-not-parentheses diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 936a164a3a2..375ad1d5459 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ PR c/65830 * c-c++-common/pr65830.c: New test. + PR c/63357 + * c-c++-common/Wlogical-op-1.c: New test. + 2015-04-24 Marek Polacek PR c/61534 diff --git a/gcc/testsuite/c-c++-common/Wlogical-op-1.c b/gcc/testsuite/c-c++-common/Wlogical-op-1.c new file mode 100644 index 00000000000..33d4f3893df --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wlogical-op-1.c @@ -0,0 +1,109 @@ +/* PR c/63357 */ +/* { dg-do compile } */ +/* { dg-options "-Wlogical-op" } */ + +#ifndef __cplusplus +# define bool _Bool +# define true 1 +# define false 0 +#endif + +extern int bar (void); +extern int *p; +struct R { int a, b; } S; + +void +andfn (int a, int b) +{ + if (a && a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (!a && !a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (!!a && !!a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a > 0 && a > 0) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a < 0 && a < 0) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a == 0 && a == 0) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a <= 0 && a <= 0) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a >= 0 && a >= 0) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (a == 0 && !(a != 0)) {} /* { dg-warning "logical .and. of equal expressions" } */ + + if (a && a && a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if ((a + 1) && (a + 1)) {} /* { dg-warning "logical .and. of equal expressions" } */ + if ((10 * a) && (a * 10)) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (!!a && a) {} /* { dg-warning "logical .and. of equal expressions" } */ + + if (*p && *p) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (p[0] && p[0]) {} /* { dg-warning "logical .and. of equal expressions" } */ + if (S.a && S.a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if ((bool) a && (bool) a) {} /* { dg-warning "logical .and. of equal expressions" } */ + if ((unsigned) a && a) {} /* { dg-warning "logical .and. of equal expressions" } */ + + /* Stay quiet here. */ + if (a && b) {} + if (!a && !b) {} + if (!!a && !!b) {} + if (a > 0 && b > 0) {} + if (a < 0 && b < 0) {} + if (a == 0 && b == 0) {} + if (a <= 0 && b <= 0) {} + if (a >= 0 && b >= 0) {} + + if (a > 0 && a > 1) {} + if (a > -2 && a > 1) {} + if (a && (short) a) {} + if ((char) a && a) {} + if (++a && a) {} + if (++a && ++a) {} + if (a && --a) {} + if (a && a / 2) {} + if (bar () && bar ()) {} + if (p && *p) {} + if (p[0] && p[1]) {} + if (S.a && S.b) {} +} + +void +orfn (int a, int b) +{ + if (a || a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (!a || !a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (!!a || !!a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a > 0 || a > 0) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a < 0 || a < 0) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a == 0 || a == 0) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a <= 0 || a <= 0) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a >= 0 || a >= 0) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (a == 0 || !(a != 0)) {} /* { dg-warning "logical .or. of equal expressions" } */ + + if (a || a || a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if ((a + 1) || (a + 1)) {} /* { dg-warning "logical .or. of equal expressions" } */ + if ((10 * a) || (a * 10)) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (!!a || a) {} /* { dg-warning "logical .or. of equal expressions" } */ + + if (*p || *p) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (p[0] || p[0]) {} /* { dg-warning "logical .or. of equal expressions" } */ + if (S.a || S.a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if ((bool) a || (bool) a) {} /* { dg-warning "logical .or. of equal expressions" } */ + if ((unsigned) a || a) {} /* { dg-warning "logical .or. of equal expressions" } */ + + /* Stay quiet here. */ + if (a || b) {} + if (!a || !b) {} + if (!!a || !!b) {} + if (a > 0 || b > 0) {} + if (a < 0 || b < 0) {} + if (a == 0 || b == 0) {} + if (a <= 0 || b <= 0) {} + if (a >= 0 || b >= 0) {} + + if (a > 0 || a > 1) {} + if (a > -2 || a > 1) {} + if (a || (short) a) {} + if ((char) a || a) {} + if (++a || a) {} + if (++a || ++a) {} + if (a || --a) {} + if (a || a / 2) {} + if (bar () || bar ()) {} + if (p || *p) {} + if (p[0] || p[1]) {} + if (S.a || S.b) {} +} -- 2.11.4.GIT