@@ -681,7 +681,7 @@ class IRGuardCondition extends Instruction {
681
681
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
682
682
cached
683
683
predicate comparesEq ( Operand op , int k , boolean areEqual , AbstractValue value ) {
684
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value )
684
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value )
685
685
}
686
686
687
687
/**
@@ -703,7 +703,7 @@ class IRGuardCondition extends Instruction {
703
703
cached
704
704
predicate ensuresEq ( Operand op , int k , IRBlock block , boolean areEqual ) {
705
705
exists ( AbstractValue value |
706
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
706
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
707
707
this .valueControls ( block , value )
708
708
)
709
709
}
@@ -729,7 +729,7 @@ class IRGuardCondition extends Instruction {
729
729
cached
730
730
predicate ensuresEqEdge ( Operand op , int k , IRBlock pred , IRBlock succ , boolean areEqual ) {
731
731
exists ( AbstractValue value |
732
- unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , false , value ) and
732
+ unary_compares_eq ( valueNumber ( this ) , op , k , areEqual , value ) and
733
733
this .valueControlsEdge ( pred , succ , value )
734
734
)
735
735
}
@@ -866,72 +866,34 @@ private predicate compares_eq(
866
866
867
867
/**
868
868
* Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
869
- *
870
- * Many internal predicates in this file have a `inNonZeroCase` column.
871
- * Ideally, the `k` column would be a type such as `Option<int>::Option`, to
872
- * represent whether we have a concrete value `k` such that `op == k`, or whether
873
- * we only know that `op != 0`.
874
- * However, cannot instantiate `Option` with an infinite type. Thus the boolean
875
- * `inNonZeroCase` is used to distinquish the `Some` (where we have a concrete
876
- * value `k`) and `None` cases (where we only know that `op != 0`).
877
- *
878
- * Thus, if `inNonZeroCase = true` then `op != 0` and the value of `k` is
879
- * meaningless.
880
- *
881
- * To see why `inNonZeroCase` is needed consider the following C program:
882
- * ```c
883
- * char* p = ...;
884
- * if(p) {
885
- * use(p);
886
- * }
887
- * ```
888
- * in C++ there would be an int-to-bool conversion on `p`. However, since C
889
- * does not have booleans there is no conversion. We want to be able to
890
- * conclude that `p` is non-zero in the true branch, so we need to give `k`
891
- * some value. However, simply setting `k = 1` would make the rest of the
892
- * analysis think that `k == 1` holds inside the branch. So we distinquish
893
- * between the above case and
894
- * ```c
895
- * if(p == 1) {
896
- * use(p)
897
- * }
898
- * ```
899
- * by setting `inNonZeroCase` to `true` in the former case, but not in the
900
- * latter.
901
869
*/
902
870
private predicate unary_compares_eq (
903
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase , AbstractValue value
871
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
904
872
) {
905
873
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
906
- exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , inNonZeroCase , v ) |
874
+ exists ( AbstractValue v | unary_simple_comparison_eq ( test , op , k , v ) |
907
875
areEqual = true and value = v
908
876
or
909
877
areEqual = false and value = v .getDualValue ( )
910
878
)
911
879
or
912
- unary_complex_eq ( test , op , k , areEqual , inNonZeroCase , value )
880
+ unary_complex_eq ( test , op , k , areEqual , value )
913
881
or
914
882
/* (x is true => (op == k)) => (!x is false => (op == k)) */
915
- exists ( AbstractValue dual , boolean inNonZeroCase0 |
883
+ exists ( AbstractValue dual |
916
884
value = dual .getDualValue ( ) and
917
- unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , inNonZeroCase0 , areEqual , dual )
918
- |
919
- k = 0 and inNonZeroCase = inNonZeroCase0
920
- or
921
- k != 0 and inNonZeroCase = true
885
+ unary_compares_eq ( test .( LogicalNotValueNumber ) .getUnary ( ) , op , k , areEqual , dual )
922
886
)
923
887
or
924
888
// ((test is `areEqual` => op == const + k2) and const == `k1`) =>
925
889
// test is `areEqual` => op == k1 + k2
926
- inNonZeroCase = false and
927
890
exists ( int k1 , int k2 , Instruction const |
928
891
compares_eq ( test , op , const .getAUse ( ) , k2 , areEqual , value ) and
929
892
int_value ( const ) = k1 and
930
893
k = k1 + k2
931
894
)
932
895
or
933
- unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual ,
934
- inNonZeroCase , value )
896
+ unary_compares_eq ( test .( BuiltinExpectCallValueNumber ) .getCondition ( ) , op , k , areEqual , value )
935
897
}
936
898
937
899
/** Rearrange various simple comparisons into `left == right + k` form. */
@@ -1000,27 +962,24 @@ private predicate isRelevantUnaryComparisonOperand(Operand op) {
1000
962
1001
963
/** Rearrange various simple comparisons into `op == k` form. */
1002
964
private predicate unary_simple_comparison_eq (
1003
- ValueNumber test , Operand op , int k , boolean inNonZeroCase , AbstractValue value
965
+ ValueNumber test , Operand op , int k , AbstractValue value
1004
966
) {
1005
967
exists ( CaseEdge case , SwitchConditionValueNumber condition |
1006
968
condition = test and
1007
969
op = condition .getExpressionOperand ( ) and
1008
970
case = value .( MatchValue ) .getCase ( ) and
1009
971
exists ( condition .getSuccessor ( case ) ) and
1010
- case .getValue ( ) .toInt ( ) = k and
1011
- inNonZeroCase = false
972
+ case .getValue ( ) .toInt ( ) = k
1012
973
)
1013
974
or
1014
975
isRelevantUnaryComparisonOperand ( op ) and
1015
976
op .getDef ( ) = test .getAnInstruction ( ) and
1016
977
(
1017
978
k = 1 and
1018
- value .( BooleanValue ) .getValue ( ) = true and
1019
- inNonZeroCase = true
979
+ value .( BooleanValue ) .getValue ( ) = true
1020
980
or
1021
981
k = 0 and
1022
- value .( BooleanValue ) .getValue ( ) = false and
1023
- inNonZeroCase = false
982
+ value .( BooleanValue ) .getValue ( ) = false
1024
983
)
1025
984
}
1026
985
@@ -1074,13 +1033,12 @@ private predicate complex_eq(
1074
1033
* an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
1075
1034
*/
1076
1035
private predicate unary_builtin_expect_eq (
1077
- CompareValueNumber cmp , Operand op , int k , boolean areEqual , boolean inNonZeroCase ,
1078
- AbstractValue value
1036
+ CompareValueNumber cmp , Operand op , int k , boolean areEqual , AbstractValue value
1079
1037
) {
1080
1038
exists ( BuiltinExpectCallValueNumber call , Instruction const , AbstractValue innerValue |
1081
1039
int_value ( const ) = 0 and
1082
1040
cmp .hasOperands ( call .getAUse ( ) , const .getAUse ( ) ) and
1083
- unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , inNonZeroCase , innerValue )
1041
+ unary_compares_eq ( call .getCondition ( ) , op , k , areEqual , innerValue )
1084
1042
|
1085
1043
cmp instanceof CompareNEValueNumber and
1086
1044
value = innerValue
@@ -1091,13 +1049,13 @@ private predicate unary_builtin_expect_eq(
1091
1049
}
1092
1050
1093
1051
private predicate unary_complex_eq (
1094
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase , AbstractValue value
1052
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
1095
1053
) {
1096
- unary_sub_eq ( test , op , k , areEqual , inNonZeroCase , value )
1054
+ unary_sub_eq ( test , op , k , areEqual , value )
1097
1055
or
1098
- unary_add_eq ( test , op , k , areEqual , inNonZeroCase , value )
1056
+ unary_add_eq ( test , op , k , areEqual , value )
1099
1057
or
1100
- unary_builtin_expect_eq ( test , op , k , areEqual , inNonZeroCase , value )
1058
+ unary_builtin_expect_eq ( test , op , k , areEqual , value )
1101
1059
}
1102
1060
1103
1061
/*
@@ -1357,19 +1315,17 @@ private predicate sub_eq(
1357
1315
1358
1316
// op - x == c => op == (c+x)
1359
1317
private predicate unary_sub_eq (
1360
- ValueNumber test , Operand op , int k , boolean areEqual , boolean inNonZeroCase , AbstractValue value
1318
+ ValueNumber test , Operand op , int k , boolean areEqual , AbstractValue value
1361
1319
) {
1362
- inNonZeroCase = false and
1363
1320
exists ( SubInstruction sub , int c , int x |
1364
- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1321
+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
1365
1322
op = sub .getLeftOperand ( ) and
1366
1323
x = int_value ( sub .getRight ( ) ) and
1367
1324
k = c + x
1368
1325
)
1369
1326
or
1370
- inNonZeroCase = false and
1371
1327
exists ( PointerSubInstruction sub , int c , int x |
1372
- unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1328
+ unary_compares_eq ( test , sub .getAUse ( ) , c , areEqual , value ) and
1373
1329
op = sub .getLeftOperand ( ) and
1374
1330
x = int_value ( sub .getRight ( ) ) and
1375
1331
k = c + x
@@ -1424,12 +1380,10 @@ private predicate add_eq(
1424
1380
1425
1381
// left + x == right + c => left == right + (c-x)
1426
1382
private predicate unary_add_eq (
1427
- ValueNumber test , Operand left , int k , boolean areEqual , boolean inNonZeroCase ,
1428
- AbstractValue value
1383
+ ValueNumber test , Operand left , int k , boolean areEqual , AbstractValue value
1429
1384
) {
1430
- inNonZeroCase = false and
1431
1385
exists ( AddInstruction lhs , int c , int x |
1432
- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1386
+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
1433
1387
(
1434
1388
left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
1435
1389
or
@@ -1438,9 +1392,8 @@ private predicate unary_add_eq(
1438
1392
k = c - x
1439
1393
)
1440
1394
or
1441
- inNonZeroCase = false and
1442
1395
exists ( PointerAddInstruction lhs , int c , int x |
1443
- unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , inNonZeroCase , value ) and
1396
+ unary_compares_eq ( test , lhs .getAUse ( ) , c , areEqual , value ) and
1444
1397
(
1445
1398
left = lhs .getLeftOperand ( ) and x = int_value ( lhs .getRight ( ) )
1446
1399
or
0 commit comments