Bitwise & or | joining comparison results in a condition
ID |
objectivec.correctness.bitwise_in_conditional |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
medium |
Remediation Effort |
low |
Resource |
Suspicious Code |
Language |
Objective-C |
Description
Reports a single & or | in the condition of an if or a while where one of its two operands is a comparison, which is the shape a mistyped && or || leaves behind. A plain bit-mask test such as if (options & NSCaseInsensitiveSearch) or if ((flags & kMask) != 0) is not reported: there the bitwise operator is intended, and the rule requires the comparison to sit directly beside the operator rather than around a parenthesised sub-expression. Shifts and the → arrow are not mistaken for comparisons.
Rationale
& and | do not short-circuit, so if (node != nil & node→count > 0) evaluates the right-hand side even when the left is false and crashes on exactly the input the guard was written for. When both sides are comparisons the result is usually still correct, because the operands are 0 or 1 and the bit operation agrees with the logical one, which is what makes the typo survive testing — until an operand becomes a value other than zero or one, such as a function returning 2 for a truthy result, and the condition silently starts producing the wrong answer. Either way the reader sees a bit operation where a boolean was meant.
The following code illustrates the pattern detected by this rule:
@implementation Gate
- (void)bothComparisons:(NSInteger)x y:(NSInteger)y {
// FLAGGED: Bitwise & or | joining comparison results in a condition
if (x == 1 & y == 2) {
[self open];
}
}
- (void)open {
}
- (BOOL)isReady {
return YES;
}
@end