Python: CG trace: Handle multiple calls on one line

Reduced number of InvalidRecordedCall from 16 to 2. This is the calls

```
one(); one()
```

since they are not distinguishable from the expression.
This commit is contained in:
Rasmus Wriedt Larsen
2020-07-20 14:07:09 +02:00
parent a1c1ab080b
commit cb98f4433d
2 changed files with 56 additions and 4 deletions

View File

@@ -0,0 +1,32 @@
import python
abstract class XMLBytecodeExpr extends XMLElement {
}
class XMLBytecodeVariableName extends XMLBytecodeExpr {
XMLBytecodeVariableName() { this.hasName("BytecodeVariableName") }
string get_name_data() { result = this.getAChild("name").getTextValue() }
}
class XMLBytecodeAttribute extends XMLBytecodeExpr {
XMLBytecodeAttribute() { this.hasName("BytecodeAttribute") }
string get_attr_name_data() { result = this.getAChild("attr_name").getTextValue() }
XMLBytecodeExpr get_object_data() {
result.getParent() = this.getAChild("object")
}
}
class XMLBytecodeCall extends XMLBytecodeExpr {
XMLBytecodeCall() { this.hasName("BytecodeCall") }
XMLBytecodeExpr get_function_data() {
result.getParent() = this.getAChild("function")
}
}
class XMLBytecodeUnknown extends XMLBytecodeExpr {
XMLBytecodeUnknown() { this.hasName("BytecodeUnknown") }
}

View File

@@ -1,13 +1,12 @@
import python
import semmle.python.types.Builtins
import semmle.python.objects.Callables
import BytecodeExpr
class XMLRecordedCall extends XMLElement {
XMLRecordedCall() { this.hasName("recorded_call") }
Call getCall() {
result = this.getXMLCall().getCall()
}
Call getCall() { result = this.getXMLCall().getCall() }
XMLCall getXMLCall() { result.getParent() = this }
@@ -25,7 +24,28 @@ class XMLCall extends XMLElement {
Call getCall() {
// TODO: do we handle calls spanning multiple lines?
result.getLocation().hasLocationInfo(this.get_filename_data(), this.get_linenum_data(), _, _, _)
this.matchBytecodeExpr(result, this.getAChild("bytecode_expr").getAChild())
}
private predicate matchBytecodeExpr(Expr expr, XMLBytecodeExpr bytecode) {
exists(Call parent_call, XMLBytecodeCall parent_bytecode_call |
parent_call
.getLocation()
.hasLocationInfo(this.get_filename_data(), this.get_linenum_data(), _, _, _) and
parent_call.getAChildNode*() = expr and
parent_bytecode_call.getParent() = this.getAChild("bytecode_expr") and
parent_bytecode_call.getAChild*() = bytecode
) and
(
expr.(Name).getId() = bytecode.(XMLBytecodeVariableName).get_name_data()
or
expr.(Attribute).getName() = bytecode.(XMLBytecodeAttribute).get_attr_name_data() and
matchBytecodeExpr(expr.(Attribute).getObject(),
bytecode.(XMLBytecodeAttribute).get_object_data())
or
matchBytecodeExpr(expr.(Call).getFunc(),
bytecode.(XMLBytecodeCall).get_function_data())
)
}
}