diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 9f3042ebb5b7..466b08922819 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1643,16 +1643,24 @@ private module ReturnNodes { } } - pragma[noinline] - private AstNode implicitReturn(Callable c, ExprNode n) { - exists(CfgNodes::ExprCfgNode en | - en = n.getExprNode() and - en.getASuccessor().(CfgNodes::AnnotatedExitNode).isNormal() and - n.(NodeImpl).getCfgScope() = c and - result = en.getExpr() - ) + private AstNode desugar(AstNode n) { + result = n.getDesugared() + or + not exists(n.getDesugared()) and + result = n + } + + private Expr getLast(StmtSequence s) { + result = getLast(s.(BodyStmt).getElse()) or - result = implicitReturn(c, n).getParent() + result = getLast(s.(BodyStmt).getARescue().getBody()) + or + not exists(s.(BodyStmt).getElse()) and + exists(Stmt last | last = s.getLastStmt() | + result = getLast(last) + or + result = last and not last instanceof StmtSequence + ) } /** @@ -1661,7 +1669,7 @@ private module ReturnNodes { * last thing that is evaluated in the body of the callable. */ class ExprReturnNode extends SourceReturnNode, ExprNode { - ExprReturnNode() { exists(Callable c | implicitReturn(c, this) = c.getBody().getAStmt()) } + ExprReturnNode() { this.getExprNode().getExpr() = desugar(getLast(any(Callable c).getBody())) } override ReturnKind getKindSource() { exists(CfgScope scope | scope = this.(NodeImpl).getCfgScope() |