Merge pull request #13612 from asgerf/rb/api-graph-explicit-proc-lambda

Ruby: Improve support for explicit proc-creation
This commit is contained in:
Asger F
2023-07-14 13:02:44 +02:00
committed by GitHub
4 changed files with 31 additions and 1 deletions

View File

@@ -978,6 +978,12 @@ module API {
pred = Impl::MkModuleInstanceUp(mod) and
succ = getBackwardEndNode(mod.getOwnInstanceMethod("call"))
)
or
// Step through callable wrappers like `proc` and `lambda` calls.
exists(DataFlow::Node node |
pred = getBackwardEndNode(node) and
succ = getBackwardStartNode(node.asCallable())
)
}
pragma[nomagic]

View File

@@ -1333,11 +1333,20 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
creation.asExpr() =
any(CfgNodes::ExprNodes::MethodCallCfgNode mc |
c.asCallable() = mc.getBlock().getExpr() and
mc.getExpr().getMethodName() = ["lambda", "proc"]
isProcCreationCall(mc.getExpr())
)
)
}
/** Holds if `call` is a call to `lambda`, `proc`, or `Proc.new` */
pragma[nomagic]
private predicate isProcCreationCall(MethodCall call) {
call.getMethodName() = ["proc", "lambda"]
or
call.getMethodName() = "new" and
call.getReceiver().(ConstantReadAccess).getAQualifiedName() = "Proc"
}
/**
* Holds if `call` is a from-source lambda call of kind `kind` where `receiver`
* is the lambda expression.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Improved resolution of calls performed on an object created with `Proc.new`.

View File

@@ -0,0 +1,11 @@
Foo.bar proc { |x|
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
}
Foo.bar lambda { |x|
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
}
Foo.bar Proc.new { |x|
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
}