Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ final class DataFlowCall extends TDataFlowCall {
/** Gets the underlying call, if any. */
Call asCall() { this = TCall(result) }

predicate isImplicitDerefCall(AstNode n, DerefChain derefChain, int i, Function target) {
this = TImplicitDerefCall(n, derefChain, i, target)
predicate isImplicitDerefCall(Expr e, DerefChain derefChain, int i, Function target) {
this = TImplicitDerefCall(e, derefChain, i, target)
}

predicate isSummaryCall(
Expand All @@ -75,18 +75,17 @@ final class DataFlowCall extends TDataFlowCall {
DataFlowCallable getEnclosingCallable() {
result.asCfgScope() = this.asCall().getEnclosingCfgScope()
or
result.asCfgScope() =
any(AstNode n | this.isImplicitDerefCall(n, _, _, _)).getEnclosingCfgScope()
result.asCfgScope() = any(Expr e | this.isImplicitDerefCall(e, _, _, _)).getEnclosingCfgScope()
or
this.isSummaryCall(result.asSummarizedCallable(), _)
}

string toString() {
result = this.asCall().toString()
or
exists(AstNode n, DerefChain derefChain, int i |
this.isImplicitDerefCall(n, derefChain, i, _) and
result = "[implicit deref call " + i + " in " + derefChain.toString() + "] " + n
exists(Expr e, DerefChain derefChain, int i |
this.isImplicitDerefCall(e, derefChain, i, _) and
result = "[implicit deref call " + i + " in " + derefChain.toString() + "] " + e
)
or
exists(
Expand All @@ -100,7 +99,7 @@ final class DataFlowCall extends TDataFlowCall {
Location getLocation() {
result = this.asCall().getLocation()
or
result = any(AstNode n | this.isImplicitDerefCall(n, _, _, _)).getLocation()
result = any(Expr e | this.isImplicitDerefCall(e, _, _, _)).getLocation()
}
}

Expand Down Expand Up @@ -1082,9 +1081,10 @@ private module Cached {
Stages::DataFlowStage::ref() and
call.hasEnclosingCfgScope()
} or
TImplicitDerefCall(AstNode n, DerefChain derefChain, int i, Function target) {
TypeInference::implicitDerefChainBorrow(n, derefChain, _) and
target = derefChain.getElement(i).getDerefFunction()
TImplicitDerefCall(Expr e, DerefChain derefChain, int i, Function target) {
TypeInference::implicitDerefChainBorrow(e, derefChain, _) and
target = derefChain.getElement(i).getDerefFunction() and
e.hasEnclosingCfgScope()
} or
TSummaryCall(
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
Expand Down
56 changes: 29 additions & 27 deletions rust/ql/lib/codeql/rust/dataflow/internal/Node.qll
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,11 @@ abstract class ImplicitDerefBorrowNode extends Node {
*/
abstract Node getBorrowInputNode();

abstract AstNode getUnderlyingAstNode();
abstract Expr getExpr();

override CfgScope getCfgScope() { result = this.getUnderlyingAstNode().getEnclosingCfgScope() }
override CfgScope getCfgScope() { result = this.getExpr().getEnclosingCfgScope() }

override Location getLocation() { result = this.getUnderlyingAstNode().getLocation() }
override Location getLocation() { result = this.getExpr().getLocation() }
}

/**
Expand All @@ -292,24 +292,24 @@ abstract class ImplicitDerefBorrowNode extends Node {
* is in.
*/
class ImplicitDerefNode extends ImplicitDerefBorrowNode, TImplicitDerefNode {
AstNode n;
Expr e;
DerefChain derefChain;
ImplicitDerefNodeState state;
int i;

ImplicitDerefNode() { this = TImplicitDerefNode(n, derefChain, state, i, false) }
ImplicitDerefNode() { this = TImplicitDerefNode(e, derefChain, state, i, false) }

override AstNode getUnderlyingAstNode() { result = n }
override Expr getExpr() { result = e }

private predicate isBuiltinDeref() { derefChain.isBuiltinDeref(i) }

private Node getInputNode() {
// The first implicit deref has the underlying AST node as input
i = 0 and
result.(AstNodeNode).getAstNode() = n
result.asExpr() = e
or
// Subsequent implicit derefs have the previous implicit deref as input
result = TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(), i - 1, false)
result = TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(), i - 1, false)
}

/**
Expand All @@ -334,19 +334,19 @@ class ImplicitDerefNode extends ImplicitDerefBorrowNode, TImplicitDerefNode {
*/
Node getDerefOutputNode() {
state = TImplicitDerefNodeBeforeDerefState() and
result = TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(), i, false)
result = TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(), i, false)
}

/**
* Holds if this node represents the last implicit deref in the underlying chain.
*/
predicate isLast(AstNode node) {
node = n and
predicate isLast(Expr expr) {
expr = e and
state = TImplicitDerefNodeAfterDerefState() and
i = derefChain.length() - 1
}

override string toString() { result = n + " [implicit deref " + i + " in state " + state + "]" }
override string toString() { result = e + " [implicit deref " + i + " in state " + state + "]" }
}

final class ImplicitDerefArgNode extends ImplicitDerefNode, ArgumentNode {
Expand All @@ -356,12 +356,12 @@ final class ImplicitDerefArgNode extends ImplicitDerefNode, ArgumentNode {
ImplicitDerefArgNode() {
not derefChain.isBuiltinDeref(i) and
state = TImplicitDerefNodeAfterBorrowState() and
call_.isImplicitDerefCall(n, derefChain, i, _) and
call_.isImplicitDerefCall(e, derefChain, i, _) and
pos_.isSelf()
or
this.isLast(_) and
TypeInference::implicitDerefChainBorrow(n, derefChain, false) and
isArgumentForCall(n, call_.asCall(), pos_)
TypeInference::implicitDerefChainBorrow(e, derefChain, false) and
isArgumentForCall(e, call_.asCall(), pos_)
}

override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
Expand All @@ -378,7 +378,7 @@ private class ImplicitDerefOutNode extends ImplicitDerefNode, OutNode {
}

override DataFlowCall getCall(ReturnKind kind) {
result.isImplicitDerefCall(n, derefChain, i, _) and
result.isImplicitDerefCall(e, derefChain, i, _) and
kind = TNormalReturnKind()
}
}
Expand All @@ -387,30 +387,30 @@ private class ImplicitDerefOutNode extends ImplicitDerefNode, OutNode {
* A node that represents the value of an expression _after_ implicit borrowing.
*/
class ImplicitBorrowNode extends ImplicitDerefBorrowNode, TImplicitBorrowNode {
AstNode n;
Expr e;
DerefChain derefChain;

ImplicitBorrowNode() { this = TImplicitBorrowNode(n, derefChain, false) }
ImplicitBorrowNode() { this = TImplicitBorrowNode(e, derefChain, false) }

override AstNode getUnderlyingAstNode() { result = n }
override Expr getExpr() { result = e }

override Node getBorrowInputNode() {
result =
TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(),
TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(),
derefChain.length() - 1, false)
or
derefChain.isEmpty() and
result.(AstNodeNode).getAstNode() = n
result.(AstNodeNode).getAstNode() = e
}

override string toString() { result = n + " [implicit borrow]" }
override string toString() { result = e + " [implicit borrow]" }
}

final class ImplicitBorrowArgNode extends ImplicitBorrowNode, ArgumentNode {
private DataFlowCall call_;
private RustDataFlow::ArgumentPosition pos_;

ImplicitBorrowArgNode() { isArgumentForCall(n, call_.asCall(), pos_) }
ImplicitBorrowArgNode() { isArgumentForCall(e, call_.asCall(), pos_) }

override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
call = call_ and pos = pos_
Expand Down Expand Up @@ -736,13 +736,15 @@ newtype TNode =
)
} or
TImplicitDerefNode(
AstNode n, DerefChain derefChain, ImplicitDerefNodeState state, int i, Boolean isPost
Expr e, DerefChain derefChain, ImplicitDerefNodeState state, int i, Boolean isPost
) {
TypeInference::implicitDerefChainBorrow(n, derefChain, _) and
e.hasEnclosingCfgScope() and
TypeInference::implicitDerefChainBorrow(e, derefChain, _) and
i in [0 .. derefChain.length() - 1]
} or
TImplicitBorrowNode(AstNode n, DerefChain derefChain, Boolean isPost) {
TypeInference::implicitDerefChainBorrow(n, derefChain, true)
TImplicitBorrowNode(Expr e, DerefChain derefChain, Boolean isPost) {
e.hasEnclosingCfgScope() and
TypeInference::implicitDerefChainBorrow(e, derefChain, true)
} or
TDerefOutNode(DerefExpr de, Boolean isPost) or
TIndexOutNode(IndexExpr ie, Boolean isPost) or
Expand Down
Loading