Add a new warning, "Possible precedence problem on bitwise
Rafael Garcia-Suarez [Thu, 3 Oct 2002 20:26:54 +0000 (20:26 +0000)]
%c operator", triggerred when a bitwise op has a numeric
comparison op as child.

p4raw-id: //depot/perl@17972

op.c
pod/perldiag.pod
t/lib/warnings/op

diff --git a/op.c b/op.c
index c7d085c..85c0740 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4737,7 +4737,29 @@ Perl_ck_anoncode(pTHX_ OP *o)
 OP *
 Perl_ck_bitop(pTHX_ OP *o)
 {
+#define OP_IS_NUMCOMPARE(op) \
+       ((op) == OP_LT   || (op) == OP_I_LT || \
+        (op) == OP_GT   || (op) == OP_I_GT || \
+        (op) == OP_LE   || (op) == OP_I_LE || \
+        (op) == OP_GE   || (op) == OP_I_GE || \
+        (op) == OP_EQ   || (op) == OP_I_EQ || \
+        (op) == OP_NE   || (op) == OP_I_NE || \
+        (op) == OP_NCMP || (op) == OP_I_NCMP)
     o->op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
+    if (o->op_type == OP_BIT_OR
+           || o->op_type == OP_BIT_AND
+           || o->op_type == OP_BIT_XOR)
+    {
+       OPCODE typfirst = cBINOPo->op_first->op_type;
+       OPCODE typlast  = cBINOPo->op_first->op_sibling->op_type;
+       if (OP_IS_NUMCOMPARE(typfirst) || OP_IS_NUMCOMPARE(typlast))
+           if (ckWARN(WARN_PRECEDENCE))
+               Perl_warner(aTHX_ packWARN(WARN_PRECEDENCE),
+                       "Possible precedence problem on bitwise %c operator",
+                       o->op_type == OP_BIT_OR ? '|'
+                           : o->op_type == OP_BIT_AND ? '&' : '^'
+                       );
+    }
     return o;
 }
 
index 40f9929..f174a91 100644 (file)
@@ -2928,6 +2928,18 @@ Perl guesses a reasonable buffer size, but puts a sentinel byte at the
 end of the buffer just in case.  This sentinel byte got clobbered, and
 Perl assumes that memory is now corrupted.  See L<perlfunc/ioctl>.
 
+=item Possible precedence problem on bitwise %c operator
+
+(W precedence) Your program uses a bitwise logical operator in conjunction
+with a numeric comparison operator, like this :
+
+    if ($x & $y == 0) { ... }
+
+This expression is actually equivalent to C<$x & ($y == 0)>, due to the
+higher precedence of C<==>. This is probably not what you want. (If you
+really meant to write this, disable the warning, or, better, write
+C<$x & ($y == 0 ? 1 : 0)>).
+
 =item Possible unintended interpolation of %s in string
 
 (W ambiguous) You said something like `@foo' in a double-quoted string
index 98f55a4..1e39c0e 100644 (file)
 
     Use of /g modifier is meaningless in split
 
+    Possible precedence problem on bitwise %c operator [Perl_ck_bitop]
+
     Mandatory Warnings 
     ------------------
     Prototype mismatch:                [cv_ckproto]
     oops: oopsAV               [oopsAV]        TODO
     oops: oopsHV               [oopsHV]        TODO
     
-
 __END__
 # op.c
 use warnings 'misc' ;
@@ -971,3 +972,56 @@ no warnings 'regexp';
 split /blah/g, "blah";
 EXPECT
 Use of /g modifier is meaningless in split at - line 4.
+########
+# op.c
+use warnings 'precedence';
+$a = $b & $c == $d;
+$a = $b ^ $c != $d;
+$a = $b | $c > $d;
+$a = $b < $c & $d;
+$a = $b >= $c ^ $d;
+$a = $b <= $c | $d;
+$a = $b <=> $c & $d;
+no warnings 'precedence';
+$a = $b & $c == $d;
+$a = $b ^ $c != $d;
+$a = $b | $c > $d;
+$a = $b < $c & $d;
+$a = $b >= $c ^ $d;
+$a = $b <= $c | $d;
+$a = $b <=> $c & $d;
+EXPECT
+Possible precedence problem on bitwise & operator at - line 3.
+Possible precedence problem on bitwise ^ operator at - line 4.
+Possible precedence problem on bitwise | operator at - line 5.
+Possible precedence problem on bitwise & operator at - line 6.
+Possible precedence problem on bitwise ^ operator at - line 7.
+Possible precedence problem on bitwise | operator at - line 8.
+Possible precedence problem on bitwise & operator at - line 9.
+########
+# op.c
+use integer;
+use warnings 'precedence';
+$a = $b & $c == $d;
+$a = $b ^ $c != $d;
+$a = $b | $c > $d;
+$a = $b < $c & $d;
+$a = $b >= $c ^ $d;
+$a = $b <= $c | $d;
+$a = $b <=> $c & $d;
+no warnings 'precedence';
+$a = $b & $c == $d;
+$a = $b ^ $c != $d;
+$a = $b | $c > $d;
+$a = $b < $c & $d;
+$a = $b >= $c ^ $d;
+$a = $b <= $c | $d;
+$a = $b <=> $c & $d;
+EXPECT
+Possible precedence problem on bitwise & operator at - line 4.
+Possible precedence problem on bitwise ^ operator at - line 5.
+Possible precedence problem on bitwise | operator at - line 6.
+Possible precedence problem on bitwise & operator at - line 7.
+Possible precedence problem on bitwise ^ operator at - line 8.
+Possible precedence problem on bitwise | operator at - line 9.
+Possible precedence problem on bitwise & operator at - line 10.