-
Notifications
You must be signed in to change notification settings - Fork 1.9k
JS: Use guard nodes in useless-conditionals #380
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
JS: Use guard nodes in useless-conditionals #380
Conversation
ghost
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, except for bullet 3.
For !p it will report that the variable p is always true/false, rather than pointing to the whole !p expression
I fear that this will make the query results too easy to mis-interpret.
The believe the query already confuse users of the LGTM interface that fail to check exactly what region the alert message is for. This will make it worse for complex expressions since we no longer report the actual value of a guard.
Consider:
if (!(complex1(complex2())) {
// ^^^^^^^^^^^^^^^^^^^^ // this expression always evaluate to false
} else {
// so this code is dead
}|
That alert could indeed be confusing. Unfortunately, I can't write a test case that reproduces the example since return-type inference is not in yet. At the moment it will always highlight a variable or a trivially truthy expression like I believe we got a report from a user about this once. I can't seem to find it now, but I believe this change would actually have fixed it. It would have mentioned the variable itself in the alert message instead of highlighting something like I propose to keep this change, but once return-type inference lands, add another special case for function invocations, similar to what we have for variables. |
It is, if the callee is a function complex1(v){
return v
}
function complex2(){
return true;
}
if (!(complex1(complex2())) {
// ^^^^^^^^^^^^^^^^^^^^ // this expression always evaluate to false
} else {
// so this code is dead
} |
|
Okay so the |
9ebae0c to
1568d5d
Compare
|
I've rebased to avoid conflicts, although now the test for |
ghost
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved. I have an idea for making the alert less confusing, I will open up a separate PR for that.
|
Oh, sorry, that was a bit quick. I was also trying out some ideas but nothing quite worked out so far. I started an evaluation last night: https://git.semmle.com/asger/dist-compare-reports/tree/domitian.ti.semmle.com_1540941089548 One of the results looks a bit fishy, the one about I think the problem is that there is an outgoing guard node from the rightmost This is objectively a false positive, so we should probably revert this and rethink. |
|
Sorry about that, I read the rebase comment as if you were done. Will you open the revert? |
|
I'll revert when I get in. |
|
I'll put up another PR that just addresses the first two bullet points after the revert has merged. |
This changes
useless-conditionalto useConditionGuardNodeas the basis to determine if something is a condition. This has a few consequences:zinif (x && z)as a conditional. Previously onlyxandx && zwere recognised.!pit will report that the variablepis always true/false, rather than pointing to the whole!pexpression.pinstead of!p. This means trivial expressions like!trueandtrue && truewill not be reported anymore, sincetrueis already whitelisted.The two latter ones are debatable, but for now I've just kept it like this for simplicity.
Moving to
ConditionGuardNodeis also necessary in order to report range analysis results with this query. Putting this up separately so the results won't interfere with the evaluation of range analysis.