@@ -591,24 +591,6 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
591
591
delta = D:: fromInt ( 0 ) and
592
592
( upper = true or upper = false )
593
593
or
594
- exists ( SemExpr x | e2 .( SemAddExpr ) .hasOperands ( e1 , x ) |
595
- // `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
596
- not x instanceof SemConstantIntegerExpr and
597
- not e1 instanceof SemConstantIntegerExpr and
598
- if strictlyPositiveIntegralExpr ( x )
599
- then upper = false and delta = D:: fromInt ( 1 )
600
- else
601
- if semPositive ( x )
602
- then upper = false and delta = D:: fromInt ( 0 )
603
- else
604
- if strictlyNegativeIntegralExpr ( x )
605
- then upper = true and delta = D:: fromInt ( - 1 )
606
- else
607
- if semNegative ( x )
608
- then upper = true and delta = D:: fromInt ( 0 )
609
- else none ( )
610
- )
611
- or
612
594
exists ( SemExpr x , SemSubExpr sub |
613
595
e2 = sub and
614
596
sub .getLeftOperand ( ) = e1 and
@@ -1043,13 +1025,44 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
1043
1025
delta = D:: fromFloat ( f ) and
1044
1026
if semPositive ( e ) then f >= 0 else any ( )
1045
1027
)
1028
+ or
1029
+ exists (
1030
+ SemBound bLeft , SemBound bRight , D:: Delta dLeft , D:: Delta dRight , boolean fbeLeft ,
1031
+ boolean fbeRight , D:: Delta odLeft , D:: Delta odRight , SemReason rLeft , SemReason rRight
1032
+ |
1033
+ boundedAddOperand ( e , upper , bLeft , false , dLeft , fbeLeft , odLeft , rLeft ) and
1034
+ boundedAddOperand ( e , upper , bRight , true , dRight , fbeRight , odRight , rRight ) and
1035
+ delta = D:: fromFloat ( D:: toFloat ( dLeft ) + D:: toFloat ( dRight ) ) and
1036
+ fromBackEdge = fbeLeft .booleanOr ( fbeRight )
1037
+ |
1038
+ b = bLeft and origdelta = odLeft and reason = rLeft and bRight instanceof SemZeroBound
1039
+ or
1040
+ b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
1041
+ )
1046
1042
)
1047
1043
}
1048
1044
1045
+ pragma [ nomagic]
1049
1046
private predicate boundedConditionalExpr (
1050
1047
SemConditionalExpr cond , SemBound b , boolean upper , boolean branch , D:: Delta delta ,
1051
1048
boolean fromBackEdge , D:: Delta origdelta , SemReason reason
1052
1049
) {
1053
1050
bounded ( cond .getBranchExpr ( branch ) , b , delta , upper , fromBackEdge , origdelta , reason )
1054
1051
}
1052
+
1053
+ pragma [ nomagic]
1054
+ private predicate boundedAddOperand (
1055
+ SemAddExpr add , boolean upper , SemBound b , boolean isLeft , D:: Delta delta , boolean fromBackEdge ,
1056
+ D:: Delta origdelta , SemReason reason
1057
+ ) {
1058
+ // `semValueFlowStep` already handles the case where one of the operands is a constant.
1059
+ not semValueFlowStep ( add , _, _) and
1060
+ (
1061
+ isLeft = true and
1062
+ bounded ( add .getLeftOperand ( ) , b , delta , upper , fromBackEdge , origdelta , reason )
1063
+ or
1064
+ isLeft = false and
1065
+ bounded ( add .getRightOperand ( ) , b , delta , upper , fromBackEdge , origdelta , reason )
1066
+ )
1067
+ }
1055
1068
}
0 commit comments