Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bbfea44

Browse files
committed
Python: CG trace: Handle multiple calls to same func on same line
Such as ``` one(); one() ``` Now there are no InvalidRecordedCall in the current examples.
1 parent cb98f44 commit bbfea44

1 file changed

Lines changed: 33 additions & 2 deletions

File tree

python/tools/recorded-call-graph-metrics/ql/RecordedCalls.qll

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ class XMLRecordedCall extends XMLElement {
1111
XMLCall getXMLCall() { result.getParent() = this }
1212

1313
XMLCallee getXMLCallee() { result.getParent() = this }
14+
15+
/** Get a different `XMLRecordedCall` with the same result-set for `getCall`. */
16+
XMLRecordedCall getOtherWithSameSetOfCalls() {
17+
// `rc` is for a different bytecode instruction on same line
18+
not result.getXMLCall().get_inst_index_data() = this.getXMLCall().get_inst_index_data() and
19+
result.getXMLCall().get_filename_data() = this.getXMLCall().get_filename_data() and
20+
result.getXMLCall().get_linenum_data() = this.getXMLCall().get_linenum_data() and
21+
// set of calls is equal
22+
// 1. this.getCall() issubset result.getCall()
23+
not exists(Call call | call = this.getCall() | not result.getCall() = call) and
24+
// 2. result.getCall() issubset this.getCall()
25+
not exists(Call call | call = result.getCall() | not this.getCall() = call)
26+
}
1427
}
1528

1629
class XMLCall extends XMLElement {
@@ -43,8 +56,7 @@ class XMLCall extends XMLElement {
4356
matchBytecodeExpr(expr.(Attribute).getObject(),
4457
bytecode.(XMLBytecodeAttribute).get_object_data())
4558
or
46-
matchBytecodeExpr(expr.(Call).getFunc(),
47-
bytecode.(XMLBytecodeCall).get_function_data())
59+
matchBytecodeExpr(expr.(Call).getFunc(), bytecode.(XMLBytecodeCall).get_function_data())
4860
)
4961
}
5062
}
@@ -111,6 +123,25 @@ class ValidRecordedCall extends XMLRecordedCall {
111123
or
112124
strictcount(this.getXMLCallee().(XMLExternalCallee).getCallee()) = 1
113125
)
126+
or
127+
// Handle case where the same function is called multiple times in one line, for
128+
// example `func(); func()`. This only works if:
129+
// - all the callees for these calls is the same
130+
// - all these calls were recorded
131+
//
132+
// without this `strictcount`, in the case `func(); func(); func()`, if 1 of the calls
133+
// is not recorded, we woulld still mark the other two recorded calls as valid
134+
// (which is not following the rules above). + 1 to count `this` as well.
135+
strictcount(this.getCall()) = strictcount(this.getOtherWithSameSetOfCalls()) + 1 and
136+
forex(XMLRecordedCall rc |
137+
rc = this.getOtherWithSameSetOfCalls()
138+
|
139+
unique(Function f | f = this.getXMLCallee().(XMLPythonCallee).getCallee()) =
140+
unique(Function f | f = rc.getXMLCallee().(XMLPythonCallee).getCallee())
141+
or
142+
unique(Builtin b | b = this.getXMLCallee().(XMLExternalCallee).getCallee()) =
143+
unique(Builtin b | b = rc.getXMLCallee().(XMLExternalCallee).getCallee())
144+
)
114145
}
115146
}
116147

0 commit comments

Comments
 (0)