Manuel López-Ibáñez - Re: [PATCH] Implement warning for wrong use of ||/&& (original) (raw)

This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.

Hi,

the patch below implements a warning for apparently wrong usage of "||" and "&&" in contexts where likely a "|" or "&" was intended by the programmer. This seems very low false-positive to me, and it has found dozens of real faults in real world code (actually all code I tried it on, including gcc itself). I was actually trying to submit patches for those all by myself to get all the honor, but on the other hand I'm too lazy for that so I'd rather like to get the warning into gcc so that everyone can fix their code instead ;)

I've spent several hours trying to come up for a good name for this warning, but couldn't. so I've plumbed it into -Walways-true. Matches perfectly IMHO.

bootstrapped, regtested against i686-suse-linux, no regressions. Ok?

Thanks, Dirk

2007-02-13 Dirk Mueller dmueller@suse.de

    * c-typeck.c (parser_build_binary_op): Warn about expressions
    of &&/|| and non-zero constants.


    * cp/call.c (build_new_op): Warn about expressions
    of &&/|| and non-zero constants.


    * gcc.dg/Walways-true-3.c: New testcase.
    * g++.dg/warn/Walways-true-3.C: New testcase.

--- c-typeck.c (revision 121595) +++ c-typeck.c (working copy) @@ -2634,6 +2634,33 @@ parser_build_binary_op (enum tree_code c if (warn_parentheses) warn_about_parentheses (code, code1, code2);

@@ -3694,6 +3711,14 @@ build_new_op (enum tree_code code, int f case CALL_EXPR: return build_object_call (arg1, arg2);

@@ -3921,6 +3968,18 @@ build_new_op (enum tree_code code, int f case INDIRECT_REF: return build_indirect_ref (arg1, "unary *");

Index: testsuite/gcc.dg/Walways-true-3.c

--- testsuite/gcc.dg/Walways-true-3.c (revision 0) +++ testsuite/gcc.dg/Walways-true-3.c (revision 0) @@ -0,0 +1,47 @@ +/* + { dg-do compile} + { dg-options "-Walways-true" } +/ + +enum { a, ba, b }; + +enum testenum { t1, t2}; + +extern int c; +extern char bool_a, bool_b; + +extern int testa(); + +void foo() +{ + if ( testa() && b ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( c && b ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( c && 0x42 ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( c && 0x42 ) / { dg-warning "always evaluate as" } / + (void) testa(); + + if ( c && 0x80 >>6) / { dg-warning "always evaluate as" } / + (void)testa(); + + + if ( b && c == a ) / { dg-bogus "always evaluate as" } / + (void)testa(); + + if ( 1 && c ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( t2 && b ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( 0 && c == a ) / { dg-warning "always evaluate as" } / + (void)testa(); + + if ( b && 1 ) / { dg-warning "always evaluate as" } */ + (void)testa(); +} Index: testsuite/g++.dg/warn/Walways-true-3.C

--- testsuite/g++.dg/warn/Walways-true-3.C (revision 0) +++ testsuite/g++.dg/warn/Walways-true-3.C (revision 0) @@ -0,0 +1,46 @@ +// { dg-do compile} +// { dg-options "-Walways-true" } + +enum { a, b }; + +enum testenum { t1, t2}; + +extern int c; +extern bool bool_a, bool_b; + +template +class QFlags +{ +public:

+}