We do not support evaluating bitwise operations, so that when we check for
their results being null we create a new assumption whether the current new
symbol is null or non-null. If we are on the non-null assumption's branch
we need to check the left-hand side operand's constraint range informations:
- It if contradicts with the forming new constraint ranges then we create a null state as it is an impossible condition.
- Otherwise we need to remove the nullability from its ranges as we know that it cannot be null on that branch (except bitwise OR).
Let's do some math.
Suppose $x is in range [2, 3]. In this case the true range for $x & 1 is [0, 1] (because 2 & 1 == 0 and 3 & 1 == 1).
The range for $x & 8 would be [0, 0].
The range for $x | 8 would be [10, 11].
The range for $x << 1 would be [4, 4], [6, 6].
The range for $x >> 1 would be [0, 1].
None of these ranges are contained within [2, 3]. In fact, none of them even contain either 2 or 3. However, when you intersect the resulting range with [2, 3], you make sure that the resulting range is contained within [2, 3]. I don't think that's correct.