few join order fixes

This commit is contained in:
Erik Krogh Kristensen
2021-12-09 18:55:04 +01:00
parent 6eca4ba2d3
commit 758a5d7a85
3 changed files with 14 additions and 3 deletions

View File

@@ -54,6 +54,7 @@ abstract class AstNode extends AstNode_ {
}
/** Whether this contains `inner` syntactically */
pragma[nomagic]
predicate contains(AstNode inner) { this.getAChildNode+() = inner }
pragma[noinline]

View File

@@ -167,17 +167,19 @@ class Function extends Function_, Scope, AstNode {
/** A def statement. Note that FunctionDef extends Assign as a function definition binds the newly created function */
class FunctionDef extends Assign {
FunctionExpr f;
/* syntax: def name(...): ... */
FunctionDef() {
/* This is an artificial assignment the rhs of which is a (possibly decorated) FunctionExpr */
exists(FunctionExpr f | this.getValue() = f or this.getValue() = f.getADecoratorCall())
this.getValue() = f or this.getValue() = f.getADecoratorCall()
}
override string toString() { result = "FunctionDef" }
/** Gets the function for this statement */
Function getDefinedFunction() {
exists(FunctionExpr func | this.containsInScope(func) and result = func.getInnerScope())
result = f.getInnerScope() // XXX: This behaves very differently. But from inspecting the results of the previous version, that had every function in the same scope as the result.
}
override Stmt getLastStatement() { result = this.getDefinedFunction().getLastStatement() }

View File

@@ -14,6 +14,14 @@
import python
predicate isInsideLoop(AstNode node) {
node.getParentNode() instanceof While
or
node.getParentNode() instanceof For
or
exists(AstNode prev | isInsideLoop(prev) | node = prev.getAChildNode())
}
from Delete del, Expr e, Function f
where
f.getLastStatement() = del and
@@ -21,7 +29,7 @@ where
f.containsInScope(e) and
not e instanceof Subscript and
not e instanceof Attribute and
not exists(Stmt s | s.(While).contains(del) or s.(For).contains(del)) and
not isInsideLoop(del) and
// False positive: calling `sys.exc_info` within a function results in a
// reference cycle, and an explicit call to `del` helps break this cycle.
not exists(FunctionValue ex |