How to connect two alias dataflow node in Go? #17329
-
|
I am new to dataflow library for Go. I want to automatically find the alias slice reference expression with same value when executing in Go. I have a program as follows: func main() {
var s []int
s[0] = nil
s = s[1:]
}Is there any dataflow predicates I can use in dataflow library for Go to connect I tried two functions, import go
import DataFlow
predicate indexOfSlice(IndexExpr sliceIdx, SliceExpr slice) {
localFlow(exprNode(sliceIdx), exprNode(slice.getBase()))
}
from IndexExpr sliceIdx, SliceExpr slice
where indexOfSlice(sliceIdx, slice)
select sliceIdx, sliceThe result of the above query contains nothing. import go
import DataFlow
from ExprNode s, Node d
where globalValueNumber(s) = globalValueNumber(d)
select s, dI don't find I don't know which predicate I can use to connect these two node. Is there any predicate? The conditions requested in the question can be relaxed, i.e. connecting It is not a good idea to test whether results of func foo() {
a := 2
x := b.f
x.g = &a
b.f.g = &a
}Obviously, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
|
Hi @Lslightly, Thanks for your question. In the first scenario you should be able to connect For example, The second example is much more complicated because you need to keep track of aliases and match access path to relate access paths. For example, to relate An overfitted, but possible useful starting point, example is: predicate isAliasedThroughAccessPath(SsaVariable alias, SsaVariable base, string path) {
exists(SelectorExpr selector | base.getAUse().isFirstNodeOf(selector.getBase+()) |
globalValueNumber(DataFlow::ssaNode(alias)) = globalValueNumber(DataFlow::exprNode(selector))
and getAccessPath(selector) = path
)
}
string getAccessPath(SelectorExpr e) {
if e.getBase() instanceof SelectorExpr then
exists(string root | root = getAccessPath(e.getBase())|
result = root + "." + e.getSelector().getName()
)
else
result = e.getBase().(VariableName) + "." + e.getSelector().getName()
}
predicate isAliasedSelector(SelectorExpr n, SelectorExpr m) {
exists(SsaVariable baseOfN, SsaVariable baseOfM, string path |
isAliasedThroughAccessPath(baseOfN, baseOfM, path)
and baseOfN.getAUse().isFirstNodeOf(n.getBase+()) and
baseOfM.getAUse().isFirstNodeOf(m.getBase+()) and
getAccessPath(m) = getAccessPath(n).regexpReplaceAll("^"+baseOfN.getSourceVariable().getName()+"\\.", path + ".")
)
}
from SelectorExpr n, SelectorExpr m
where isAliasedSelector(n, m)
select n, mI will also ask the Go team for suggestions, because they are our CodeQL Go experts. |
Beta Was this translation helpful? Give feedback.
Hi @Lslightly,
Thanks for your question.
In the first scenario you should be able to connect
swiths[0]ands[1:]through anSSAVariableand its uses.For example,
The second example is much more complicated because you need to keep track of aliases and match access path to relate access paths.
For example, to relate
x.gandb.f.gyou can relatexwithbthroughb.fand later matchx.gwithb.f.gthrough substitution ofxin the access path with the access pathb.f.An overfitted, but possible useful starting point, example is: