mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
Add call graph test.
This test uses annotations to encode the expected output directly into the source, hence the `.expected` files are trivial.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
missingCall
|
||||
spuriousCall
|
||||
@@ -0,0 +1,11 @@
|
||||
import go
|
||||
|
||||
query predicate missingCall(DeclaredFunction f, DataFlow::CallNode call) {
|
||||
call.getACallee() = f.getFuncDecl() and
|
||||
not call = f.getACall()
|
||||
}
|
||||
|
||||
query predicate spuriousCall(DeclaredFunction f, DataFlow::CallNode call) {
|
||||
call = f.getACall() and
|
||||
exists(FuncDecl fd | fd = f.getFuncDecl() | not call.getACallee() = fd)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
missingCallee
|
||||
spuriousCallee
|
||||
@@ -0,0 +1,25 @@
|
||||
import go
|
||||
|
||||
/**
|
||||
* Gets a string `val` such that there is a comment on the same line as `l`
|
||||
* that contains the substring `key: val`.
|
||||
*/
|
||||
string metadata(Locatable l, string key) {
|
||||
exists(string f, int line, Comment c, string kv |
|
||||
l.hasLocationInfo(f, line, _, _, _) and
|
||||
c.hasLocationInfo(f, line, _, _, _) and
|
||||
kv = c.getText().regexpFind("\\b(\\w+: \\S+)", _, _) and
|
||||
key = kv.regexpCapture("(\\w+): (\\S+)", 1) and
|
||||
result = kv.regexpCapture("(\\w+): (\\S+)", 2)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate missingCallee(DataFlow::CallNode call, FuncDef callee) {
|
||||
metadata(call.asExpr(), "callee") = metadata(callee, "name") and
|
||||
not call.getACallee() = callee
|
||||
}
|
||||
|
||||
query predicate spuriousCallee(DataFlow::CallNode call, FuncDef callee) {
|
||||
call.getACallee() = callee and
|
||||
not metadata(call.asExpr(), "callee") = metadata(callee, "name")
|
||||
}
|
||||
35
ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go
Normal file
35
ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
type I interface {
|
||||
m() // name: I.m
|
||||
}
|
||||
|
||||
type s1 struct{}
|
||||
|
||||
type s2 struct{}
|
||||
|
||||
type s3 struct{}
|
||||
|
||||
type mybool bool
|
||||
|
||||
func (s1) m() {} // name: s1.m
|
||||
|
||||
func (*s2) m() {} // name: s2.m
|
||||
|
||||
func (s3) m(int) {} // name: s3.m
|
||||
|
||||
func (mybool) m() {} // name: mybool.m
|
||||
|
||||
func test(x *s1, y s2, z s3, b mybool, i I) {
|
||||
x.m() // callee: s1.m
|
||||
y.m() // callee: s2.m
|
||||
z.m(0) // callee: s3.m
|
||||
b.m() // callee: mybool.m
|
||||
i.m() // callee: s1.m callee: s2.m callee: mybool.m
|
||||
s1.m(*x) // callee: s1.m
|
||||
s3.m(z, 0) // callee: s3.m
|
||||
mybool.m(b) // callee: mybool.m
|
||||
(func() {})() // name: func(){} callee: func(){}
|
||||
id := func(x int) int { return x } // name: id
|
||||
id(1) // callee: id
|
||||
}
|
||||
Reference in New Issue
Block a user