@@ -1244,39 +1244,63 @@ module Expressions {
12441244 index = subscr .getIndex ( )
12451245 }
12461246
1247- /** Track bitwise expressions so we can handle integer flags and enums.
1248- * Tracking too many binary expressions is likely to kill performance.
1247+ /** Tracking too many binary expressions is likely to kill performance, so just say anything other than addition or bitwise or is 'unknown'.
12491248 */
12501249 pragma [ noinline]
12511250 predicate binaryPointsTo ( BinaryExprNode b , PointsToContext context , ObjectInternal value , ControlFlowNode origin , ControlFlowNode operand , ObjectInternal opvalue ) {
12521251 origin = b and
1253- exists ( ControlFlowNode left , Operator op , ControlFlowNode right |
1254- b .operands ( left , op , right )
1252+ operand = genericBinaryOperand ( b ) and
1253+ PointsToInternal:: pointsTo ( operand , context , opvalue , _) and
1254+ value = ObjectInternal:: unknown ( )
1255+ }
1256+
1257+ private ControlFlowNode genericBinaryOperand ( BinaryExprNode b ) {
1258+ exists ( Operator op |
1259+ b .operands ( result , op , _)
1260+ or
1261+ b .operands ( _, op , result )
12551262 |
12561263 not op instanceof BitOr and
1257- ( operand = left or operand = right ) and
1264+ not op instanceof Add
1265+ )
1266+ }
1267+
1268+ pragma [ noinline]
1269+ predicate addPointsTo ( BinaryExprNode b , PointsToContext context , ObjectInternal value , ControlFlowNode origin , ControlFlowNode operand , ObjectInternal opvalue ) {
1270+ origin = b and
1271+ exists ( Operator op |
1272+ b .operands ( operand , op , _)
1273+ or
1274+ b .operands ( _, op , operand )
1275+ |
1276+ op instanceof Add and
12581277 PointsToInternal:: pointsTo ( operand , context , opvalue , _) and
1259- (
1260- op instanceof Add and
1261- value = TUnknownInstance ( opvalue .getClass ( ) )
1262- or
1263- not op instanceof Add and
1264- value = ObjectInternal:: unknown ( )
1265- )
1278+ value = TUnknownInstance ( opvalue .getClass ( ) )
1279+ )
1280+ }
1281+
1282+ pragma [ noinline]
1283+ predicate bitOrPointsTo ( BinaryExprNode b , PointsToContext context , ObjectInternal value , ControlFlowNode origin , ControlFlowNode operand , ObjectInternal opvalue ) {
1284+ origin = b and
1285+ exists ( Operator op , ControlFlowNode other |
1286+ b .operands ( operand , op , other )
12661287 or
1288+ b .operands ( other , op , operand )
1289+ |
12671290 op instanceof BitOr and
1268- exists ( ObjectInternal lobj , ObjectInternal robj |
1269- PointsToInternal:: pointsTo ( left , context , lobj , _) and
1270- PointsToInternal:: pointsTo ( right , context , robj , _) and
1271- value = TInt ( lobj .intValue ( ) .bitOr ( robj .intValue ( ) ) )
1272- |
1273- left = operand and opvalue = lobj
1274- or
1275- right = operand and opvalue = robj
1291+ exists ( ObjectInternal obj , int i1 , int i2 |
1292+ pointsToInt ( operand , context , opvalue , i1 ) and
1293+ pointsToInt ( other , context , obj , i2 ) and
1294+ value = TInt ( i1 .bitOr ( i2 ) )
12761295 )
12771296 )
12781297 }
12791298
1299+ predicate pointsToInt ( ControlFlowNode n , PointsToContext context , ObjectInternal obj , int value ) {
1300+ PointsToInternal:: pointsTo ( n , context , obj , _) and
1301+ value = obj .intValue ( )
1302+ }
1303+
12801304 pragma [ noinline]
12811305 predicate unaryPointsTo ( UnaryExprNode u , PointsToContext context , ObjectInternal value , ControlFlowNode origin , ControlFlowNode operand , ObjectInternal opvalue ) {
12821306 exists ( Unaryop op |
@@ -1518,6 +1542,10 @@ module Expressions {
15181542 or
15191543 subscriptPointsTo ( expr , context , value , origin , subexpr , subvalue )
15201544 or
1545+ addPointsTo ( expr , context , value , origin , subexpr , subvalue )
1546+ or
1547+ bitOrPointsTo ( expr , context , value , origin , subexpr , subvalue )
1548+ or
15211549 binaryPointsTo ( expr , context , value , origin , subexpr , subvalue )
15221550 or
15231551 unaryPointsTo ( expr , context , value , origin , subexpr , subvalue )
0 commit comments