Rust: Value flow through macro calls

This commit is contained in:
Simon Friis Vindum
2025-01-03 13:43:56 +01:00
parent f09632df58
commit 42d125676e
7 changed files with 27 additions and 19 deletions

View File

@@ -173,6 +173,16 @@ final class MethodCallExprCfgNode extends CallExprBaseCfgNode, Nodes::MethodCall
*/
final class CallExprCfgNode extends CallExprBaseCfgNode, Nodes::CallExprCfgNode { }
final class MacroCallCfgNode extends Nodes::MacroCallCfgNode {
private MacroCallChildMapping node;
MacroCallCfgNode() { node = this.getAstNode() }
CfgNode getExpandedNode() {
any(ChildMapping mapping).hasCfgChild(node, node.getExpanded(), this, result)
}
}
/**
* A record expression. For example:
* ```rust

View File

@@ -74,6 +74,10 @@ class RecordPatChildMapping extends ParentAstNode, RecordPat {
}
}
class MacroCallChildMapping extends ParentAstNode, MacroCall {
override predicate relevantChild(AstNode child) { child = this.getExpanded() }
}
class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree {
override predicate relevantChild(AstNode child) { child = this.getChildNode(_) }
}

View File

@@ -131,24 +131,8 @@ class LetStmtTree extends PreOrderTree, LetStmt {
}
}
class MacroCallTree extends ControlFlowTree, MacroCall {
override predicate first(AstNode first) {
first(this.getExpanded(), first)
or
not exists(this.getExpanded()) and first = this
}
override predicate last(AstNode last, Completion c) {
last(this.getExpanded(), last, c)
or
not exists(this.getExpanded()) and
last = this and
completionIsValidFor(c, last)
}
override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
override predicate propagatesAbnormal(AstNode child) { child = this.getExpanded() }
class MacroCallTree extends StandardPostOrderTree, MacroCall {
override AstNode getChildNode(int i) { i = 0 and result = this.getExpanded() }
}
class MacroStmtsTree extends StandardPreOrderTree, MacroStmts {

View File

@@ -522,6 +522,7 @@ private ExprCfgNode getALastEvalNode(ExprCfgNode e) {
result = e.(BreakExprCfgNode).getExpr() or
result = e.(BlockExprCfgNode).getTailExpr() or
result = e.(MatchExprCfgNode).getArmExpr(_) or
result = e.(MacroExprCfgNode).getMacroCall().(MacroCallCfgNode).getExpandedNode() or
result.(BreakExprCfgNode).getTarget() = e
}

View File

@@ -6,6 +6,7 @@ localStep
| main.rs:7:9:7:9 | [SSA] s | main.rs:8:20:8:20 | s |
| main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s |
| main.rs:7:9:7:14 | ...: i64 | main.rs:7:9:7:9 | s |
| main.rs:8:14:8:20 | FormatArgsExpr | main.rs:8:14:8:20 | MacroExpr |
| main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s |
| main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s |
| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s |
@@ -459,7 +460,9 @@ localStep
| main.rs:410:9:410:9 | [SSA] s | main.rs:411:10:411:10 | s |
| main.rs:410:9:410:9 | s | main.rs:410:9:410:9 | [SSA] s |
| main.rs:410:13:410:27 | MacroExpr | main.rs:410:9:410:9 | s |
| main.rs:410:25:410:26 | source(...) | main.rs:410:13:410:27 | MacroExpr |
| main.rs:436:13:436:33 | result_questionmark(...) | main.rs:436:9:436:9 | _ |
| main.rs:448:36:448:41 | ...::new(...) | main.rs:448:36:448:41 | MacroExpr |
storeStep
| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text |
| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr |

View File

@@ -152,6 +152,8 @@ edges
| main.rs:385:13:385:19 | mut_arr [array[]] | main.rs:385:13:385:22 | mut_arr[1] | provenance | |
| main.rs:385:13:385:22 | mut_arr[1] | main.rs:385:9:385:9 | d | provenance | |
| main.rs:387:10:387:16 | mut_arr [array[]] | main.rs:387:10:387:19 | mut_arr[0] | provenance | |
| main.rs:410:9:410:9 | s | main.rs:411:10:411:10 | s | provenance | |
| main.rs:410:25:410:26 | source(...) | main.rs:410:9:410:9 | s | provenance | |
nodes
| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) |
| main.rs:19:9:19:9 | s | semmle.label | s |
@@ -330,6 +332,9 @@ nodes
| main.rs:386:10:386:10 | d | semmle.label | d |
| main.rs:387:10:387:16 | mut_arr [array[]] | semmle.label | mut_arr [array[]] |
| main.rs:387:10:387:19 | mut_arr[0] | semmle.label | mut_arr[0] |
| main.rs:410:9:410:9 | s | semmle.label | s |
| main.rs:410:25:410:26 | source(...) | semmle.label | source(...) |
| main.rs:411:10:411:10 | s | semmle.label | s |
subpaths
testFailures
#select
@@ -368,3 +373,4 @@ testFailures
| main.rs:375:18:375:18 | c | main.rs:370:23:370:32 | source(...) | main.rs:375:18:375:18 | c | $@ | main.rs:370:23:370:32 | source(...) | source(...) |
| main.rs:386:10:386:10 | d | main.rs:384:18:384:27 | source(...) | main.rs:386:10:386:10 | d | $@ | main.rs:384:18:384:27 | source(...) | source(...) |
| main.rs:387:10:387:19 | mut_arr[0] | main.rs:384:18:384:27 | source(...) | main.rs:387:10:387:19 | mut_arr[0] | $@ | main.rs:384:18:384:27 | source(...) | source(...) |
| main.rs:411:10:411:10 | s | main.rs:410:25:410:26 | source(...) | main.rs:411:10:411:10 | s | $@ | main.rs:410:25:410:26 | source(...) | source(...) |

View File

@@ -408,7 +408,7 @@ macro_rules! get_source {
fn macro_invocation() {
let s = get_source!(37);
sink(s); // $ MISSING: hasValueFlow=37
sink(s); // $ hasValueFlow=37
}
fn main() {