@@ -106,6 +106,9 @@ predicate analyzableExpr(Expr e) {
106106 ( e instanceof ConditionalExpr ) or
107107 ( e instanceof AddExpr ) or
108108 ( e instanceof SubExpr ) or
109+ ( e instanceof AssignExpr ) or
110+ ( e instanceof AssignAddExpr ) or
111+ ( e instanceof AssignSubExpr ) or
109112 ( e instanceof CrementOperation ) or
110113 ( e instanceof RemExpr ) or
111114 ( e instanceof CommaExpr ) or
@@ -203,6 +206,18 @@ predicate exprDependsOnDef(
203206 | e = subExpr
204207 | exprDependsOnDef ( subExpr .getAnOperand ( ) , srcDef , srcVar ) )
205208 or
209+ exists ( AssignExpr addExpr
210+ | e = addExpr
211+ | exprDependsOnDef ( addExpr .getRValue ( ) , srcDef , srcVar ) )
212+ or
213+ exists ( AssignAddExpr addExpr
214+ | e = addExpr
215+ | exprDependsOnDef ( addExpr .getAnOperand ( ) , srcDef , srcVar ) )
216+ or
217+ exists ( AssignSubExpr subExpr
218+ | e = subExpr
219+ | exprDependsOnDef ( subExpr .getAnOperand ( ) , srcDef , srcVar ) )
220+ or
206221 exists ( CrementOperation crementExpr
207222 | e = crementExpr
208223 | exprDependsOnDef ( crementExpr .getOperand ( ) , srcDef , srcVar ) )
@@ -534,6 +549,22 @@ float getLowerBoundsImpl(Expr expr) {
534549 yHigh = getFullyConvertedUpperBounds ( subExpr .getRightOperand ( ) ) and
535550 result = addRoundingDown ( xLow , - yHigh ) )
536551 or
552+ exists ( AssignExpr assign
553+ | expr = assign and
554+ result = getFullyConvertedLowerBounds ( assign .getRValue ( ) ) )
555+ or
556+ exists ( AssignAddExpr addExpr , float xLow , float yLow
557+ | expr = addExpr and
558+ xLow = getFullyConvertedLowerBounds ( addExpr .getLValue ( ) ) and
559+ yLow = getFullyConvertedLowerBounds ( addExpr .getRValue ( ) ) and
560+ result = addRoundingDown ( xLow , yLow ) )
561+ or
562+ exists ( AssignSubExpr subExpr , float xLow , float yHigh
563+ | expr = subExpr and
564+ xLow = getFullyConvertedLowerBounds ( subExpr .getLValue ( ) ) and
565+ yHigh = getFullyConvertedUpperBounds ( subExpr .getRValue ( ) ) and
566+ result = addRoundingDown ( xLow , - yHigh ) )
567+ or
537568 exists ( PrefixIncrExpr incrExpr , float xLow
538569 | expr = incrExpr and
539570 xLow = getFullyConvertedLowerBounds ( incrExpr .getOperand ( ) ) and
@@ -656,6 +687,22 @@ float getUpperBoundsImpl(Expr expr) {
656687 yLow = getFullyConvertedLowerBounds ( subExpr .getRightOperand ( ) ) and
657688 result = addRoundingUp ( xHigh , - yLow ) )
658689 or
690+ exists ( AssignExpr assign
691+ | expr = assign and
692+ result = getFullyConvertedUpperBounds ( assign .getRValue ( ) ) )
693+ or
694+ exists ( AssignAddExpr addExpr , float xHigh , float yHigh
695+ | expr = addExpr and
696+ xHigh = getFullyConvertedUpperBounds ( addExpr .getLValue ( ) ) and
697+ yHigh = getFullyConvertedUpperBounds ( addExpr .getRValue ( ) ) and
698+ result = addRoundingUp ( xHigh , yHigh ) )
699+ or
700+ exists ( AssignSubExpr subExpr , float xHigh , float yLow
701+ | expr = subExpr and
702+ xHigh = getFullyConvertedUpperBounds ( subExpr .getLValue ( ) ) and
703+ yLow = getFullyConvertedLowerBounds ( subExpr .getRValue ( ) ) and
704+ result = addRoundingUp ( xHigh , - yLow ) )
705+ or
659706 exists ( PrefixIncrExpr incrExpr , float xHigh
660707 | expr = incrExpr and
661708 xHigh = getFullyConvertedUpperBounds ( incrExpr .getOperand ( ) ) and
@@ -1156,7 +1203,7 @@ private cached module SimpleRangeAnalysisCached {
11561203 // single minimum value.
11571204 result = min ( float lb | lb = getTruncatedLowerBounds ( expr ) | lb )
11581205 }
1159-
1206+
11601207 /**
11611208 * Gets the upper bound of the expression.
11621209 *
@@ -1175,7 +1222,7 @@ private cached module SimpleRangeAnalysisCached {
11751222 // single maximum value.
11761223 result = max ( float ub | ub = getTruncatedUpperBounds ( expr ) | ub )
11771224 }
1178-
1225+
11791226 /**
11801227 * Holds if `expr` has a provably empty range. For example:
11811228 *
@@ -1204,13 +1251,13 @@ private cached module SimpleRangeAnalysisCached {
12041251 predicate defMightOverflowNegatively ( RangeSsaDefinition def , LocalScopeVariable v ) {
12051252 getDefLowerBoundsImpl ( def , v ) < varMinVal ( v )
12061253 }
1207-
1254+
12081255 /** Holds if the definition might overflow positively. */
12091256 cached
12101257 predicate defMightOverflowPositively ( RangeSsaDefinition def , LocalScopeVariable v ) {
12111258 getDefUpperBoundsImpl ( def , v ) > varMaxVal ( v )
12121259 }
1213-
1260+
12141261 /**
12151262 * Holds if the definition might overflow (either positively or
12161263 * negatively).
@@ -1220,17 +1267,22 @@ private cached module SimpleRangeAnalysisCached {
12201267 defMightOverflowNegatively ( def , v ) or
12211268 defMightOverflowPositively ( def , v )
12221269 }
1223-
1270+
12241271 /**
12251272 * Holds if the expression might overflow negatively. This predicate
12261273 * does not consider the possibility that the expression might overflow
12271274 * due to a conversion.
12281275 */
12291276 cached
12301277 predicate exprMightOverflowNegatively ( Expr expr ) {
1231- getLowerBoundsImpl ( expr ) < exprMinVal ( expr )
1278+ getLowerBoundsImpl ( expr ) < exprMinVal ( expr ) or
1279+
1280+ // The lower bound of the expression `x--` is the same as the lower
1281+ // bound of `x`, so the standard logic (above) does not work for
1282+ // detecting whether it might overflow.
1283+ getLowerBoundsImpl ( expr .( PostfixDecrExpr ) ) = exprMinVal ( expr )
12321284 }
1233-
1285+
12341286 /**
12351287 * Holds if the expression might overflow negatively. Conversions
12361288 * are also taken into account. For example the expression
@@ -1242,17 +1294,22 @@ private cached module SimpleRangeAnalysisCached {
12421294 exprMightOverflowNegatively ( expr ) or
12431295 convertedExprMightOverflowNegatively ( expr .getConversion ( ) )
12441296 }
1245-
1297+
12461298 /**
12471299 * Holds if the expression might overflow positively. This predicate
12481300 * does not consider the possibility that the expression might overflow
12491301 * due to a conversion.
12501302 */
12511303 cached
12521304 predicate exprMightOverflowPositively ( Expr expr ) {
1253- getUpperBoundsImpl ( expr ) > exprMaxVal ( expr )
1305+ getUpperBoundsImpl ( expr ) > exprMaxVal ( expr ) or
1306+
1307+ // The upper bound of the expression `x++` is the same as the upper
1308+ // bound of `x`, so the standard logic (above) does not work for
1309+ // detecting whether it might overflow.
1310+ getUpperBoundsImpl ( expr .( PostfixIncrExpr ) ) = exprMaxVal ( expr )
12541311 }
1255-
1312+
12561313 /**
12571314 * Holds if the expression might overflow positively. Conversions
12581315 * are also taken into account. For example the expression
@@ -1264,7 +1321,7 @@ private cached module SimpleRangeAnalysisCached {
12641321 exprMightOverflowPositively ( expr ) or
12651322 convertedExprMightOverflowPositively ( expr .getConversion ( ) )
12661323 }
1267-
1324+
12681325 /**
12691326 * Holds if the expression might overflow (either positively or
12701327 * negatively). The possibility that the expression might overflow
0 commit comments