Skip to content

Commit 0c9ee4d

Browse files
committed
C++: Only propagate smallest/largest bound in conditional expressions
1 parent 847f3f1 commit 0c9ee4d

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -773,22 +773,28 @@ private float getLowerBoundsImpl(Expr expr) {
773773
)
774774
)
775775
or
776-
// ConditionalExpr (true branch)
777-
exists(ConditionalExpr condExpr |
776+
exists(ConditionalExpr condExpr, Expr conv, float ub, float lb |
778777
expr = condExpr and
778+
conv = condExpr.getCondition().getFullyConverted() and
779779
// Use `boolConversionUpperBound` to determine whether the condition
780780
// might evaluate to `true`.
781-
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
782-
result = getFullyConvertedLowerBounds(condExpr.getThen())
783-
)
784-
or
785-
// ConditionalExpr (false branch)
786-
exists(ConditionalExpr condExpr |
787-
expr = condExpr and
788-
// Use `boolConversionLowerBound` to determine whether the condition
789-
// might evaluate to `false`.
790-
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
791-
result = getFullyConvertedLowerBounds(condExpr.getElse())
781+
lb = boolConversionLowerBound(conv) and
782+
ub = boolConversionUpperBound(conv)
783+
|
784+
// Both branches can be taken
785+
ub = 1 and
786+
lb = 0 and
787+
exists(float thenLb, float elseLb |
788+
thenLb = getFullyConvertedLowerBounds(condExpr.getThen()) and
789+
elseLb = getFullyConvertedLowerBounds(condExpr.getElse()) and
790+
result = thenLb.minimum(elseLb)
791+
)
792+
or
793+
// Only the `true` branch can be taken
794+
ub = 1 and lb != 0 and result = getFullyConvertedLowerBounds(condExpr.getThen())
795+
or
796+
// Only the `false` branch can be taken
797+
ub != 1 and lb = 0 and result = getFullyConvertedLowerBounds(condExpr.getElse())
792798
)
793799
or
794800
exists(AddExpr addExpr, float xLow, float yLow |
@@ -977,22 +983,28 @@ private float getUpperBoundsImpl(Expr expr) {
977983
)
978984
)
979985
or
980-
// ConditionalExpr (true branch)
981-
exists(ConditionalExpr condExpr |
986+
exists(ConditionalExpr condExpr, Expr conv, float ub, float lb |
982987
expr = condExpr and
988+
conv = condExpr.getCondition().getFullyConverted() and
983989
// Use `boolConversionUpperBound` to determine whether the condition
984990
// might evaluate to `true`.
985-
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
986-
result = getFullyConvertedUpperBounds(condExpr.getThen())
987-
)
988-
or
989-
// ConditionalExpr (false branch)
990-
exists(ConditionalExpr condExpr |
991-
expr = condExpr and
992-
// Use `boolConversionLowerBound` to determine whether the condition
993-
// might evaluate to `false`.
994-
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
995-
result = getFullyConvertedUpperBounds(condExpr.getElse())
991+
lb = boolConversionLowerBound(conv) and
992+
ub = boolConversionUpperBound(conv)
993+
|
994+
// Both branches can be taken
995+
ub = 1 and
996+
lb = 0 and
997+
exists(float thenLb, float elseLb |
998+
thenLb = getFullyConvertedUpperBounds(condExpr.getThen()) and
999+
elseLb = getFullyConvertedUpperBounds(condExpr.getElse()) and
1000+
result = thenLb.maximum(elseLb)
1001+
)
1002+
or
1003+
// Only the `true` branch can be taken
1004+
ub = 1 and lb != 0 and result = getFullyConvertedUpperBounds(condExpr.getThen())
1005+
or
1006+
// Only the `false` branch can be taken
1007+
ub != 1 and lb = 0 and result = getFullyConvertedUpperBounds(condExpr.getElse())
9961008
)
9971009
or
9981010
exists(AddExpr addExpr, float xHigh, float yHigh |

0 commit comments

Comments
 (0)