@@ -588,7 +588,7 @@ class IRGuardCondition extends Instruction {
588
588
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
589
589
pragma [ inline]
590
590
predicate comparesEq ( Operand op , int k , boolean areEqual , AbstractValue value ) {
591
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value )
591
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value )
592
592
}
593
593
594
594
/**
@@ -610,7 +610,7 @@ class IRGuardCondition extends Instruction {
610
610
pragma [ inline]
611
611
predicate ensuresEq ( Operand op , int k , IRBlock block , boolean areEqual ) {
612
612
exists ( AbstractValue value |
613
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
613
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
614
614
this .valueControls ( block , value )
615
615
)
616
616
}
@@ -636,7 +636,7 @@ class IRGuardCondition extends Instruction {
636
636
pragma [ inline]
637
637
predicate ensuresEqEdge ( Operand op , int k , IRBlock pred , IRBlock succ , boolean areEqual ) {
638
638
exists ( AbstractValue value |
639
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
639
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
640
640
this .valueControlsEdge ( pred , succ , value )
641
641
)
642
642
}
@@ -849,75 +849,35 @@ private module Cached {
849
849
850
850
/**
851
851
* Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
852
- *
853
- * Many internal predicates in this file have a `inNonZeroCase` column.
854
- * Ideally, the `k` column would be a type such as `Option<int>::Option`, to
855
- * represent whether we have a concrete value `k` such that `op == k`, or whether
856
- * we only know that `op != 0`.
857
- * However, cannot instantiate `Option` with an infinite type. Thus the boolean
858
- * `inNonZeroCase` is used to distinquish the `Some` (where we have a concrete
859
- * value `k`) and `None` cases (where we only know that `op != 0`).
860
- *
861
- * Thus, if `inNonZeroCase = true` then `op != 0` and the value of `k` is
862
- * meaningless.
863
- *
864
- * To see why `inNonZeroCase` is needed consider the following C program:
865
- * ```c
866
- * char* p = ...;
867
- * if(p) {
868
- * use(p);
869
- * }
870
- * ```
871
- * in C++ there would be an int-to-bool conversion on `p`. However, since C
872
- * does not have booleans there is no conversion. We want to be able to
873
- * conclude that `p` is non-zero in the true branch, so we need to give `k`
874
- * some value. However, simply setting `k = 1` would make the rest of the
875
- * analysis think that `k == 1` holds inside the branch. So we distinquish
876
- * between the above case and
877
- * ```c
878
- * if(p == 1) {
879
- * use(p)
880
- * }
881
- * ```
882
- * by setting `inNonZeroCase` to `true` in the former case, but not in the
883
- * latter.
884
852
*/
885
853
cached
886
854
predicate unary_compares_eq (
887
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
888
- AbstractValue value
855
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
889
856
) {
890
857
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
891
- exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , inNonZeroCase , v ) |
858
+ exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , v ) |
892
859
areEqual = true and value = v
893
860
or
894
861
areEqual = false and value = v .getDualValue ( )
895
862
)
896
863
or
897
- unary_complex_eq ( test , op , k , areEqual , inNonZeroCase , value )
864
+ unary_complex_eq ( test , op , k , areEqual , value )
898
865
or
899
866
/* (x is true => (op == k)) => (!x is false => (op == k)) */
900
- exists ( AbstractValue dual , boolean inNonZeroCase0 |
867
+ exists ( AbstractValue dual |
901
868
value = dual .getDualValue ( ) and
902
- unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , inNonZeroCase0 , areEqual ,
903
- dual )
904
- |
905
- k = 0 and inNonZeroCase = inNonZeroCase0
906
- or
907
- k != 0 and inNonZeroCase = true
869
+ unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , areEqual , dual )
908
870
)
909
871
or
910
872
// ((test is `areEqual` => op == const + k2) and const == `k1`) =>
911
873
// test is `areEqual` => op == k1 + k2
912
- inNonZeroCase = false and
913
874
exists ( int k1 , int k2 , Instruction const |
914
875
compares_eq ( test , op , const .getAUse ( ) , k2 , areEqual , value ) and
915
876
int_value ( const ) = k1 and
916
877
k = k1 + k2
917
878
)
918
879
or
919
- unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual ,
920
- inNonZeroCase , value )
880
+ unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual , value )
921
881
}
922
882
923
883
/** Rearrange various simple comparisons into `left == right + k` form. */
@@ -986,27 +946,24 @@ private module Cached {
986
946
987
947
/** Rearrange various simple comparisons into `op == k` form. */
988
948
private predicate unary_simple_comparison_eq (
989
- ValueNumber test , Operand op , int k , boolean inNonZeroCase , AbstractValue value
949
+ ValueNumber test , Operand op , int k , AbstractValue value
990
950
) {
991
951
exists ( CaseEdge case , SwitchConditionValueNumber condition |
992
952
condition = test and
993
953
op = condition .getExpressionOperand ( ) and
994
954
case = value .( MatchValue ) .getCase ( ) and
995
955
exists ( condition .getSuccessor ( case ) ) and
996
- case .getValue ( ) .toInt ( ) = k and
997
- inNonZeroCase = false
956
+ case .getValue ( ) .toInt ( ) = k
998
957
)
999
958
or
1000
959
isRelevantUnaryComparisonOperand ( op ) and
1001
960
op .getDef ( ) = test .getAnInstruction ( ) and
1002
961
(
1003
962
k = 1 and
1004
- value .( BooleanValue ) .getValue ( ) = true and
1005
- inNonZeroCase = true
963
+ value .( BooleanValue ) .getValue ( ) = true
1006
964
or
1007
965
k = 0 and
1008
- value .( BooleanValue ) .getValue ( ) = false and
1009
- inNonZeroCase = false
966
+ value .( BooleanValue ) .getValue ( ) = false
1010
967
)
1011
968
}
1012
969
@@ -1061,13 +1018,12 @@ private module Cached {
1061
1018
* an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
1062
1019
*/
1063
1020
private predicate unary_builtin_expect_eq (
1064
- CompareValueNumber cmp , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1065
- AbstractValue value
1021
+ CompareValueNumber cmp , Operand op , int k , boolean areEqual , AbstractValue value
1066
1022
) {
1067
1023
exists ( BuiltinExpectCallValueNumber call , Instruction const , AbstractValue innerValue |
1068
1024
int_value ( const ) = 0 and
1069
1025
cmp .hasOperands ( call .getAUse ( ) , const .getAUse ( ) ) and
1070
- unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , inNonZeroCase , innerValue )
1026
+ unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , innerValue )
1071
1027
|
1072
1028
cmp instanceof CompareNEValueNumber and
1073
1029
value = innerValue
@@ -1078,14 +1034,13 @@ private module Cached {
1078
1034
}
1079
1035
1080
1036
private predicate unary_complex_eq (
1081
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1082
- AbstractValue value
1037
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
1083
1038
) {
1084
- unary_sub_eq ( test , op , k , areEqual , inNonZeroCase , value )
1039
+ unary_sub_eq ( test , op , k , areEqual , value )
1085
1040
or
1086
- unary_add_eq ( test , op , k , areEqual , inNonZeroCase , value )
1041
+ unary_add_eq ( test , op , k , areEqual , value )
1087
1042
or
1088
- unary_builtin_expect_eq ( test , op , k , areEqual , inNonZeroCase , value )
1043
+ unary_builtin_expect_eq ( test , op , k , areEqual , value )
1089
1044
}
1090
1045
1091
1046
/*
@@ -1347,20 +1302,17 @@ private module Cached {
1347
1302
1348
1303
// op - x == c => op == (c+x)
1349
1304
private predicate unary_sub_eq (
1350
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1351
- AbstractValue value
1305
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
1352
1306
) {
1353
- inNonZeroCase = false and
1354
1307
exists ( SubInstruction sub , int c , int x |
1355
- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1308
+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
1356
1309
op = sub .getLeftOperand ( ) and
1357
1310
x = int_value ( sub .getRight ( ) ) and
1358
1311
k = c + x
1359
1312
)
1360
1313
or
1361
- inNonZeroCase = false and
1362
1314
exists ( PointerSubInstruction sub , int c , int x |
1363
- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1315
+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
1364
1316
op = sub .getLeftOperand ( ) and
1365
1317
x = int_value ( sub .getRight ( ) ) and
1366
1318
k = c + x
@@ -1415,12 +1367,10 @@ private module Cached {
1415
1367
1416
1368
// left + x == right + c => left == right + (c-x)
1417
1369
private predicate unary_add_eq (
1418
- ValueNumber test , Operand left , int k , boolean areEqual , boolean inNonZeroCase ,
1419
- AbstractValue value
1370
+ ValueNumber test , Operand left , int k , boolean areEqual , AbstractValue value
1420
1371
) {
1421
- inNonZeroCase = false and
1422
1372
exists ( AddInstruction lhs , int c , int x |
1423
- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1373
+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
1424
1374
(
1425
1375
left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
1426
1376
or
@@ -1429,9 +1379,8 @@ private module Cached {
1429
1379
k = c - x
1430
1380
)
1431
1381
or
1432
- inNonZeroCase = false and
1433
1382
exists ( PointerAddInstruction lhs , int c , int x |
1434
- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1383
+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
1435
1384
(
1436
1385
left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
1437
1386
or
0 commit comments