@@ -105,6 +105,9 @@ predicate analyzableExpr(Expr e) {
105105 ( e instanceof ConditionalExpr ) or
106106 ( e instanceof AddExpr ) or
107107 ( e instanceof SubExpr ) or
108+ ( e instanceof AssignExpr ) or
109+ ( e instanceof AssignAddExpr ) or
110+ ( e instanceof AssignSubExpr ) or
108111 ( e instanceof CrementOperation ) or
109112 ( e instanceof RemExpr ) or
110113 ( e instanceof CommaExpr ) or
@@ -202,6 +205,18 @@ predicate exprDependsOnDef(
202205 | e = subExpr
203206 | exprDependsOnDef ( subExpr .getAnOperand ( ) , srcDef , srcVar ) )
204207 or
208+ exists ( AssignExpr addExpr
209+ | e = addExpr
210+ | exprDependsOnDef ( addExpr .getRValue ( ) , srcDef , srcVar ) )
211+ or
212+ exists ( AssignAddExpr addExpr
213+ | e = addExpr
214+ | exprDependsOnDef ( addExpr .getAnOperand ( ) , srcDef , srcVar ) )
215+ or
216+ exists ( AssignSubExpr subExpr
217+ | e = subExpr
218+ | exprDependsOnDef ( subExpr .getAnOperand ( ) , srcDef , srcVar ) )
219+ or
205220 exists ( CrementOperation crementExpr
206221 | e = crementExpr
207222 | exprDependsOnDef ( crementExpr .getOperand ( ) , srcDef , srcVar ) )
@@ -533,6 +548,22 @@ float getLowerBoundsImpl(Expr expr) {
533548 yHigh = getFullyConvertedUpperBounds ( subExpr .getRightOperand ( ) ) and
534549 result = addRoundingDown ( xLow , - yHigh ) )
535550 or
551+ exists ( AssignExpr assign
552+ | expr = assign and
553+ result = getFullyConvertedLowerBounds ( assign .getRValue ( ) ) )
554+ or
555+ exists ( AssignAddExpr addExpr , float xLow , float yLow
556+ | expr = addExpr and
557+ xLow = getFullyConvertedLowerBounds ( addExpr .getLValue ( ) ) and
558+ yLow = getFullyConvertedLowerBounds ( addExpr .getRValue ( ) ) and
559+ result = addRoundingDown ( xLow , yLow ) )
560+ or
561+ exists ( AssignSubExpr subExpr , float xLow , float yHigh
562+ | expr = subExpr and
563+ xLow = getFullyConvertedLowerBounds ( subExpr .getLValue ( ) ) and
564+ yHigh = getFullyConvertedUpperBounds ( subExpr .getRValue ( ) ) and
565+ result = addRoundingDown ( xLow , - yHigh ) )
566+ or
536567 exists ( PrefixIncrExpr incrExpr , float xLow
537568 | expr = incrExpr and
538569 xLow = getFullyConvertedLowerBounds ( incrExpr .getOperand ( ) ) and
@@ -655,6 +686,22 @@ float getUpperBoundsImpl(Expr expr) {
655686 yLow = getFullyConvertedLowerBounds ( subExpr .getRightOperand ( ) ) and
656687 result = addRoundingUp ( xHigh , - yLow ) )
657688 or
689+ exists ( AssignExpr assign
690+ | expr = assign and
691+ result = getFullyConvertedUpperBounds ( assign .getRValue ( ) ) )
692+ or
693+ exists ( AssignAddExpr addExpr , float xHigh , float yHigh
694+ | expr = addExpr and
695+ xHigh = getFullyConvertedUpperBounds ( addExpr .getLValue ( ) ) and
696+ yHigh = getFullyConvertedUpperBounds ( addExpr .getRValue ( ) ) and
697+ result = addRoundingUp ( xHigh , yHigh ) )
698+ or
699+ exists ( AssignSubExpr subExpr , float xHigh , float yLow
700+ | expr = subExpr and
701+ xHigh = getFullyConvertedUpperBounds ( subExpr .getLValue ( ) ) and
702+ yLow = getFullyConvertedLowerBounds ( subExpr .getRValue ( ) ) and
703+ result = addRoundingUp ( xHigh , - yLow ) )
704+ or
658705 exists ( PrefixIncrExpr incrExpr , float xHigh
659706 | expr = incrExpr and
660707 xHigh = getFullyConvertedUpperBounds ( incrExpr .getOperand ( ) ) and
@@ -1132,7 +1179,7 @@ private cached module SimpleRangeAnalysisCached {
11321179 // single minimum value.
11331180 result = min ( float lb | lb = getTruncatedLowerBounds ( expr ) | lb )
11341181 }
1135-
1182+
11361183 /**
11371184 * Gets the upper bound of the expression.
11381185 *
@@ -1151,7 +1198,7 @@ private cached module SimpleRangeAnalysisCached {
11511198 // single maximum value.
11521199 result = max ( float ub | ub = getTruncatedUpperBounds ( expr ) | ub )
11531200 }
1154-
1201+
11551202 /**
11561203 * Holds if `expr` has a provably empty range. For example:
11571204 *
@@ -1180,13 +1227,13 @@ private cached module SimpleRangeAnalysisCached {
11801227 predicate defMightOverflowNegatively ( RangeSsaDefinition def , LocalScopeVariable v ) {
11811228 getDefLowerBoundsImpl ( def , v ) < varMinVal ( v )
11821229 }
1183-
1230+
11841231 /** Holds if the definition might overflow positively. */
11851232 cached
11861233 predicate defMightOverflowPositively ( RangeSsaDefinition def , LocalScopeVariable v ) {
11871234 getDefUpperBoundsImpl ( def , v ) > varMaxVal ( v )
11881235 }
1189-
1236+
11901237 /**
11911238 * Holds if the definition might overflow (either positively or
11921239 * negatively).
@@ -1196,17 +1243,22 @@ private cached module SimpleRangeAnalysisCached {
11961243 defMightOverflowNegatively ( def , v ) or
11971244 defMightOverflowPositively ( def , v )
11981245 }
1199-
1246+
12001247 /**
12011248 * Holds if the expression might overflow negatively. This predicate
12021249 * does not consider the possibility that the expression might overflow
12031250 * due to a conversion.
12041251 */
12051252 cached
12061253 predicate exprMightOverflowNegatively ( Expr expr ) {
1207- getLowerBoundsImpl ( expr ) < exprMinVal ( expr )
1254+ getLowerBoundsImpl ( expr ) < exprMinVal ( expr ) or
1255+
1256+ // The lower bound of the expression `x--` is the same as the lower
1257+ // bound of `x`, so the standard logic (above) does not work for
1258+ // detecting whether it might overflow.
1259+ getLowerBoundsImpl ( expr .( PostfixDecrExpr ) ) = exprMinVal ( expr )
12081260 }
1209-
1261+
12101262 /**
12111263 * Holds if the expression might overflow negatively. Conversions
12121264 * are also taken into account. For example the expression
@@ -1218,17 +1270,22 @@ private cached module SimpleRangeAnalysisCached {
12181270 exprMightOverflowNegatively ( expr ) or
12191271 convertedExprMightOverflowNegatively ( expr .getConversion ( ) )
12201272 }
1221-
1273+
12221274 /**
12231275 * Holds if the expression might overflow positively. This predicate
12241276 * does not consider the possibility that the expression might overflow
12251277 * due to a conversion.
12261278 */
12271279 cached
12281280 predicate exprMightOverflowPositively ( Expr expr ) {
1229- getUpperBoundsImpl ( expr ) > exprMaxVal ( expr )
1281+ getUpperBoundsImpl ( expr ) > exprMaxVal ( expr ) or
1282+
1283+ // The upper bound of the expression `x++` is the same as the upper
1284+ // bound of `x`, so the standard logic (above) does not work for
1285+ // detecting whether it might overflow.
1286+ getUpperBoundsImpl ( expr .( PostfixIncrExpr ) ) = exprMaxVal ( expr )
12301287 }
1231-
1288+
12321289 /**
12331290 * Holds if the expression might overflow positively. Conversions
12341291 * are also taken into account. For example the expression
@@ -1240,7 +1297,7 @@ private cached module SimpleRangeAnalysisCached {
12401297 exprMightOverflowPositively ( expr ) or
12411298 convertedExprMightOverflowPositively ( expr .getConversion ( ) )
12421299 }
1243-
1300+
12441301 /**
12451302 * Holds if the expression might overflow (either positively or
12461303 * negatively). The possibility that the expression might overflow
0 commit comments