Merge pull request #20863 from hvitved/rust/call-refactor

Rust: Restructure classes representing calls
This commit is contained in:
Tom Hvitved
2025-12-04 17:02:17 +01:00
committed by GitHub
88 changed files with 15977 additions and 1281 deletions

View File

@@ -30,10 +30,8 @@ class CtorAttr extends Attr {
/**
* A call into the Rust standard library, that is, a sink for this query.
*/
class StdCall extends Expr {
StdCall() {
this.(CallExprBase).getStaticTarget().getCanonicalPath().matches(["std::%", "<std::%"])
}
class StdCall extends Call {
StdCall() { this.getStaticTarget().getCanonicalPath().matches(["std::%", "<std::%"]) }
}
class PathElement = AstNode;
@@ -56,11 +54,11 @@ predicate edgesFwd(PathElement pred, PathElement succ) {
or
// [forwards reachable] callable -> enclosed call
edgesFwd(_, pred) and
pred = succ.(CallExprBase).getEnclosingCallable()
pred = succ.(Call).getEnclosingCallable()
or
// [forwards reachable] call -> target callable
edgesFwd(_, pred) and
pred.(CallExprBase).getStaticTarget() = succ
pred.(Call).getStaticTarget() = succ
}
/**

View File

@@ -6,6 +6,7 @@
import rust
import codeql.util.ReportStats
import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
import codeql.rust.internal.TypeInference as TypeInference
/**
@@ -19,22 +20,22 @@ private class RelevantFile extends File {
}
module CallTargetStats implements StatsSig {
// TODO: Take other calls into account
abstract private class CallExprBase extends InvocationExpr { }
private class CallExprCallExprBase extends CallExpr, CallExprBase { }
private class MethodCallExprCallExprBase extends MethodCallExpr, CallExprBase { }
int getNumberOfOk() {
result =
count(CallExprBase c | c.getFile() instanceof RelevantFile and exists(c.getStaticTarget()))
}
private predicate isLambdaCall(CallExpr call) {
exists(Expr receiver | receiver = call.getFunction() |
// All calls to complex expressions and local variable accesses are lambda calls
receiver instanceof PathExpr implies receiver = any(Variable v).getAnAccess()
)
count(CallExprBase c | c.getFile() instanceof RelevantFile and exists(c.getResolvedTarget()))
}
additional predicate isNotOkCall(CallExprBase c) {
c.getFile() instanceof RelevantFile and
not exists(c.getStaticTarget()) and
not isLambdaCall(c)
not exists(c.getResolvedTarget()) and
not c instanceof CallExprImpl::DynamicCallExpr
}
int getNumberOfNotOk() { result = count(CallExprBase c | isNotOkCall(c)) }

View File

@@ -67,8 +67,9 @@ module ModelGeneratorCommonInput implements
string parameterExactAccess(R::ParamBase p) {
result =
"Argument[" + any(DataFlowImpl::ParameterPosition pos | p = pos.getParameterIn(_)).toString() +
"]"
"Argument[" +
any(DataFlowImpl::RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_))
.toString() + "]"
}
string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) }
@@ -78,12 +79,16 @@ module ModelGeneratorCommonInput implements
}
bindingset[c]
string paramReturnNodeAsApproximateOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) {
string paramReturnNodeAsApproximateOutput(
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
) {
result = paramReturnNodeAsExactOutput(c, pos)
}
bindingset[c]
string paramReturnNodeAsExactOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) {
string paramReturnNodeAsExactOutput(
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
) {
result = parameterExactAccess(c.getFunction().getParam(pos.getPosition()))
or
pos.isSelf() and result = qualifierString()