-
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
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** Provides predicates for debugging the simple range analysis library. */ | |
| private module Debug { | |
| 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) | |
| } | |
| } |
Uh oh!
There was an error while loading. Please reload this page.