JS: be conservative in presence of NaN comments

This commit is contained in:
Asger F
2018-10-23 15:36:41 +01:00
parent feb8a8c4fd
commit 43df9538bf
2 changed files with 32 additions and 1 deletions

View File

@@ -69,7 +69,7 @@ import javascript
*
* CAVEATS:
*
* - We assume !(x <= y) means x > y, ignoring NaN.
* - We assume !(x <= y) means x > y, ignoring NaN, unless a nearby comment or identifier mentions NaN.
*
* - We assume integer arithmetic is exact, ignoring values above 2^53.
*
@@ -257,6 +257,24 @@ module RangeAnalysis {
)
}
/**
* Holds if the given container has a comment or identifier mentioning `NaN`.
*/
predicate hasNaNIndicator(StmtContainer container) {
exists (Comment comment |
comment.getText().regexpMatch("(?s).*N[aA]N.*") and
comment.getFile() = container.getFile() and
(
comment.getLocation().getStartLine() >= container.getLocation().getStartLine() and
comment.getLocation().getEndLine() <= container.getLocation().getEndLine()
or
comment.getNextToken() = container.getFirstToken()
))
or
exists (Identifier id | id.getName() = "NaN" or id.getName() = "isNaN" |
id.getContainer() = container)
}
/**
* Holds if `guard` asserts that the outcome of `A <op> B + bias` is true, where `<op>` is a comparison operator.
*/
@@ -266,6 +284,7 @@ module RangeAnalysis {
(
guard.getOutcome() = true and operator = compare.getOperator()
or
not hasNaNIndicator(guard.getContainer()) and
guard.getOutcome() = false and operator = negateOperator(compare.getOperator())
)
)

View File

@@ -50,3 +50,15 @@ function h(x, y) {
if (x > y) {} // NOT OK - always true
}
}
function nan(x) {
// This is a NaN comment.
if (x - 1 < x) {} // OK
}
/**
* This is a NAN comment.
*/
function nan2(x) {
if (x - 1 < x) {} // OK
}