4444
4545import cpp
4646private import RangeAnalysisUtils
47+ private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
4748import RangeSSA
4849import SimpleRangeAnalysisCached
4950private import NanAnalysis
@@ -213,6 +214,9 @@ private predicate analyzableExpr(Expr e) {
213214 or
214215 // `>>` by a constant
215216 exists ( e .( RShiftExpr ) .getRightOperand ( ) .getValue ( ) )
217+ or
218+ // A modeled expression for range analysis
219+ e instanceof SimpleRangeAnalysisExpr
216220 )
217221}
218222
@@ -328,6 +332,16 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
328332 )
329333 or
330334 e = srcDef .getAUse ( srcVar )
335+ or
336+ // A modeled expression for range analysis
337+ exists ( SimpleRangeAnalysisExpr rae | rae = e |
338+ rae .dependsOnDef ( srcDef , srcVar )
339+ or
340+ exists ( Expr child |
341+ rae .dependsOnChild ( child ) and
342+ exprDependsOnDef ( child , srcDef , srcVar )
343+ )
344+ )
331345}
332346
333347/**
@@ -445,13 +459,6 @@ private float addRoundingDownSmall(float x, float small) {
445459 if ( x + small ) - x > small then result = ( x + small ) .nextDown ( ) else result = ( x + small )
446460}
447461
448- /**
449- * Gets the truncated lower bounds of the fully converted expression.
450- */
451- private float getFullyConvertedLowerBounds ( Expr expr ) {
452- result = getTruncatedLowerBounds ( expr .getFullyConverted ( ) )
453- }
454-
455462/**
456463 * Gets the lower bounds of the expression.
457464 *
@@ -498,13 +505,6 @@ private float getTruncatedLowerBounds(Expr expr) {
498505 result = exprMinVal ( expr )
499506}
500507
501- /**
502- * Gets the truncated upper bounds of the fully converted expression.
503- */
504- private float getFullyConvertedUpperBounds ( Expr expr ) {
505- result = getTruncatedUpperBounds ( expr .getFullyConverted ( ) )
506- }
507-
508508/**
509509 * Gets the upper bounds of the expression.
510510 *
@@ -728,7 +728,9 @@ private float getLowerBoundsImpl(Expr expr) {
728728 or
729729 // Use SSA to get the lower bounds for a variable use.
730730 exists ( RangeSsaDefinition def , StackVariable v | expr = def .getAUse ( v ) |
731- result = getDefLowerBounds ( def , v )
731+ result = getDefLowerBounds ( def , v ) and
732+ // Not explicitly modeled by a SimpleRangeAnalysisExpr
733+ not expr instanceof SimpleRangeAnalysisExpr
732734 )
733735 or
734736 // unsigned `&` (tighter bounds may exist)
@@ -744,6 +746,12 @@ private float getLowerBoundsImpl(Expr expr) {
744746 right = rsExpr .getRightOperand ( ) .getFullyConverted ( ) .getValue ( ) .toInt ( ) and
745747 result = safeFloor ( left / 2 .pow ( right ) )
746748 )
749+ or
750+ // A modeled expression for range analysis
751+ exists ( SimpleRangeAnalysisExpr rangeAnalysisExpr |
752+ rangeAnalysisExpr = expr and
753+ result = rangeAnalysisExpr .getLowerBounds ( )
754+ )
747755}
748756
749757/** Only to be called by `getTruncatedUpperBounds`. */
@@ -902,7 +910,9 @@ private float getUpperBoundsImpl(Expr expr) {
902910 or
903911 // Use SSA to get the upper bounds for a variable use.
904912 exists ( RangeSsaDefinition def , StackVariable v | expr = def .getAUse ( v ) |
905- result = getDefUpperBounds ( def , v )
913+ result = getDefUpperBounds ( def , v ) and
914+ // Not explicitly modeled by a SimpleRangeAnalysisExpr
915+ not expr instanceof SimpleRangeAnalysisExpr
906916 )
907917 or
908918 // unsigned `&` (tighter bounds may exist)
@@ -920,6 +930,12 @@ private float getUpperBoundsImpl(Expr expr) {
920930 right = rsExpr .getRightOperand ( ) .getFullyConverted ( ) .getValue ( ) .toInt ( ) and
921931 result = safeFloor ( left / 2 .pow ( right ) )
922932 )
933+ or
934+ // A modeled expression for range analysis
935+ exists ( SimpleRangeAnalysisExpr rangeAnalysisExpr |
936+ rangeAnalysisExpr = expr and
937+ result = rangeAnalysisExpr .getUpperBounds ( )
938+ )
923939}
924940
925941/**
@@ -1504,3 +1520,25 @@ private module SimpleRangeAnalysisCached {
15041520 convertedExprMightOverflowPositively ( expr )
15051521 }
15061522}
1523+
1524+ /**
1525+ * INTERNAL: do not use. This module contains utilities for use in the
1526+ * experimental `SimpleRangeAnalysisExpr` module.
1527+ */
1528+ module SimpleRangeAnalysisInternal {
1529+ /**
1530+ * Gets the truncated lower bounds of the fully converted expression.
1531+ */
1532+ float getFullyConvertedLowerBounds ( Expr expr ) {
1533+ result = getTruncatedLowerBounds ( expr .getFullyConverted ( ) )
1534+ }
1535+
1536+ /**
1537+ * Gets the truncated upper bounds of the fully converted expression.
1538+ */
1539+ float getFullyConvertedUpperBounds ( Expr expr ) {
1540+ result = getTruncatedUpperBounds ( expr .getFullyConverted ( ) )
1541+ }
1542+ }
1543+
1544+ private import SimpleRangeAnalysisInternal
0 commit comments