JS: Range analysis library

This commit is contained in:
Asger F
2018-09-12 18:37:21 +01:00
parent d991fa84b1
commit a374540c55
6 changed files with 482 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
import javascript
class AssertionComment extends LineComment {
boolean isOK;
AssertionComment() {
isOK = true and getText().trim().regexpMatch("OK.*")
or
isOK = false and getText().trim().regexpMatch("NOT OK.*")
}
ConditionGuardNode getAGuardNode() {
result.getLocation().getStartLine() = this.getLocation().getStartLine() and
result.getFile() = this.getFile()
}
Expr getTestExpr() { result = getAGuardNode().getTest() }
string getMessage() {
not exists(getAGuardNode()) and result = "Error: no guard node on this line"
or
isOK = true and
exists (ConditionGuardNode guard | guard = getAGuardNode() |
RangeAnalysis::isContradictoryGuardNode(guard) and
result = "Error: analysis claims " + getTestExpr() + " is always " + guard.getOutcome().booleanNot()
)
or
isOK = false and
not RangeAnalysis::isContradictoryGuardNode(getAGuardNode()) and
result = "Error: " + getTestExpr() + " is always true or always false"
}
}
from AssertionComment assertion
select assertion, assertion.getMessage()

View File

@@ -0,0 +1,28 @@
function f(x,y) {
if (x + 1 < y) {
if (x < y) {} // NOT OK - always true
if (x + 1 < y) {} // NOT OK - always true
if (x + 1 <= y) {} // NOT OK - always true
if (x > y) {} // NOT OK - always false
if (x >= y) {} // NOT OK - always false
if (x + 1 >= y) {} // NOT OK - always false
if (x + 2 < y) {} // OK
if (x < y - 1) {} // NOT OK - always true
}
if (x < y + 1) {
if (x < y) {} // OK
if (x + 1 < y) {} // OK
if (x - 1 < y) {} // NOT OK - always true
}
}
function g(x) {
let z = x + 1;
z += 1;
++z;
z++;
if (z < x + 4) {} // NOT OK - always false
if (z > x + 4) {} // NOT OK - always false
if (z < x + 5) {} // NOT OK - always true
if (z > x + 5) {} // NOT OK - always false
}

View File

@@ -0,0 +1,52 @@
function f(x,y) {
if (x < y) {
if (x < y) {} // NOT OK - always true
if (x <= y) {} // NOT OK - always true
if (x > y) {} // NOT OK - always false
if (x >= y) {} // NOT OK - always false
if (x === y) {} // NOT OK - always false
} else {
if (x < y) {} // NOT OK - always false
if (x <= y) {} // OK - could be equal
if (x > y) {} // OK
if (x >= y) {} // NOT OK - always true
if (x === y) {} // OK
}
}
function g(x,y) {
if (x <= y) {
if (x < y) {} // OK
if (x <= y) {} // NOT OK - always true
if (x > y) {} // NOT OK - always false
if (x >= y) {} // OK - could be equal
if (x === y) {} // OK
} else {
if (x < y) {} // NOT OK - always false
if (x <= y) {} // NOT OK - always false
if (x > y) {} // NOT OK - always true
if (x >= y) {} // NOT OK - always true
if (x === y) {} // NOT OK - always false
}
}
function loop(start, end) {
var i;
for (i = start; i < end; i++) {
if (i < end) {} // NOT OK - always true
if (i >= end) {} // NOT OK - always false
}
if (i >= end) {} // NOT OK - always true
if (i < end) {} // NOT OK - always false
}
function h(x, y) {
if (x - y < 0) {
if (x < y) {} // NOT OK - always true
if (x >= y) {} // NOT OK - always false
}
if (0 < x - y) { // y < x
if (x <= y) {} // NOT OK - always false
if (x > y) {} // NOT OK - always true
}
}