-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Range analysis guard improvement #20584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a72589d
3039345
31e95e1
c4f9212
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1397,6 +1397,20 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nanExcludingComparison(guard, branch) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Adjusts a lower bound to its meaning for integral types. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Examples: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `>= 3.0` becomes `3.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* ` > 3.0` becomes `4.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `>= 3.5` becomes `4.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* ` > 3.5` becomes `4.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bindingset[strictness, lb] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private float adjustLowerBoundIntegral(RelationStrictness strictness, float lb) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if strictness = Nonstrict() and lb.floor() = lb then result = lb else result = safeFloor(lb) + 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* If the guard is a comparison of the form `p*v + q <CMP> r`, then this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* predicate uses the bounds information for `r` to compute a lower bound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1408,15 +1422,27 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if nonNanGuardedVariable(guard, v, branch) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strictness = Nonstrict() or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
not getVariableRangeType(v.getTarget()) instanceof IntegralType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then lb = childLB | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else lb = childLB + 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if getVariableRangeType(v.getTarget()) instanceof IntegralType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then lb = adjustLowerBoundIntegral(strictness, childLB) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else lb = childLB | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else lb = varMinVal(v.getTarget()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Adjusts an upper bound to its meaning for integral types. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Examples: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `<= 3.0` becomes `3.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* ` < 3.0` becomes `2.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* `<= 3.5` becomes `3.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* ` < 3.5` becomes `3.0` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bindingset[strictness, ub] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private float adjustUpperBoundIntegral(RelationStrictness strictness, float ub) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if strictness = Strict() and ub.floor() = ub then result = ub - 1 else result = safeFloor(ub) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* If the guard is a comparison of the form `p*v + q <CMP> r`, then this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* predicate uses the bounds information for `r` to compute a upper bound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1428,11 +1454,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if nonNanGuardedVariable(guard, v, branch) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strictness = Nonstrict() or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
not getVariableRangeType(v.getTarget()) instanceof IntegralType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then ub = childUB | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else ub = childUB - 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if getVariableRangeType(v.getTarget()) instanceof IntegralType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
then ub = adjustUpperBoundIntegral(strictness, childUB) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else ub = childUB | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else ub = varMaxVal(v.getTarget()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1472,7 +1496,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* lower or upper bound for `v`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private predicate linearBoundFromGuard( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ComparisonOperation guard, VariableAccess v, float p, float q, float boundValue, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ComparisonOperation guard, VariableAccess v, float p, float q, float r, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
boolean isLowerBound, // Is this a lower or an upper bound? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RelationStrictness strictness, boolean branch // Which control-flow branch is this bound valid on? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1487,11 +1511,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isLowerBound = directionIsGreater(dir) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strictness = st and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getBounds(rhs, boundValue, isLowerBound) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getBounds(rhs, r, isLowerBound) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isLowerBound = directionIsLesser(dir) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strictness = Nonstrict() and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exprTypeBounds(rhs, boundValue, isLowerBound) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exprTypeBounds(rhs, r, isLowerBound) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// For x == RHS, we create the following bounds: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1502,7 +1526,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exists(Expr lhs, Expr rhs | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
linearAccess(lhs, v, p, q) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
eqOpWithSwapAndNegate(guard, lhs, rhs, true, branch) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getBounds(rhs, boundValue, isLowerBound) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getBounds(rhs, r, isLowerBound) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strictness = Nonstrict() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// x != RHS and !x are handled elsewhere | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1860,3 +1884,34 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defMightOverflowNegatively(def, v) and result = varMaxVal(v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** Provides predicates for debugging the simple range analysis library. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private module Debug { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Dead code Warning
This code is never used, and it's not publicly exported.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Locatable getRelevantLocatable() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exists(string filepath, int startline | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result.getLocation().hasLocationInfo(filepath, startline, _, _, _) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
filepath.matches("%/test.c") and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
startline = [464 .. 472] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float debugGetFullyConvertedLowerBounds(Expr expr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expr = getRelevantLocatable() and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = getFullyConvertedLowerBounds(expr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float debugGetLowerBoundsImpl(Expr e, string kl) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
e = getRelevantLocatable() and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = getLowerBoundsImpl(e) and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
kl = e.getPrimaryQlClasses() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Counts the number of lower bounds for a given expression. This predicate is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* useful for identifying performance issues in the range analysis. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
predicate nrOfLowerBounds(Expr e, int n) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
e = getRelevantLocatable() and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
n = strictcount(float lb | lb = getLowerBoundsImpl(e) | lb) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1888
to
+1917
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This debug module should be removed before merging to production. It contains hardcoded file paths and line numbers specific to testing, which makes it inappropriate for production code.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
Uh oh!
There was an error while loading. Please reload this page.