Skip to content

Commit 262a74d

Browse files
committed
Ruby: Avoid computing full fastTC for AstNode::getParent
DIL before ``` /* AST::AstNode */ AST#87953007::Cached::TAstNode result) = fastTC(AST#a6718388::AstNode::getAChild#0#dispred#ff/2) . Completion#445d5844::mayRaise#1#f(/* Call::Call */ unique AST#87953007::Cached::TAstNode c) :- exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#2 | exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( project#Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), project#ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, call_result#2) ), ( (c = call_result#2, Call#841c84e8::Call#f(c)); ( #AST#a6718388::AstNode::getAChild#0#dispredPlus#ff(call_result#2, c), Call#841c84e8::Call#f(c) ) ) ) . ``` DIL after ``` incremental Completion#445d5844::getARescuableBodyChild#0#f(/* AST::AstNode */ unique AST#87953007::Cached::TAstNode result) :- exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( exists(dontcare int _, /* Expr::RescueClause */ dontcare AST#87953007::Cached::TAstNode _1 | Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst, _, _1) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), exists(boolean arg2, dontcare int _ | arg2 = true, ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, _, arg2, result) ) ); exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#5 | rec Completion#445d5844::getARescuableBodyChild#0#f(call_result#5), exists(cached dontcare string _ | AST#a6718388::AstNode::getAChild#1#dispred(call_result#5, _, result) ) ) | [base_case] exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ AST#87953007::Cached::TAstNode bst | ( ( project#Expr#6fb2af19::BodyStmt::getRescue#1#dispred#fff(bst), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ); ( exists(/* Expr::StmtSequence */ dontcare AST#87953007::Cached::TAstNode _ | Expr#6fb2af19::BodyStmt::getEnsure#0#dispred#ff(bst, _) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst) ) ), ControlFlowGraphImpl#288ae92e::Trees::BodyStmtTree#class#f(bst), project#ControlFlowGraphImpl#288ae92e::Trees::StmtSequenceTree::getBodyChild#2#dispred#ffff(bst, result) ) | [delta_order] exists(/* AST::AstNode */ AST#87953007::Cached::TAstNode call_result#5 | delta previous rec Completion#445d5844::getARescuableBodyChild#0#f(call_result#5), project#AST#a6718388::AstNode::getAChild#1#dispred(call_result#5, result) ), not(previous rec Completion#445d5844::getARescuableBodyChild#0#f(result)) . ```
1 parent d707c52 commit 262a74d

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,23 @@ private predicate completionIsValidForStmt(AstNode n, Completion c) {
7171
c = TReturnCompletion()
7272
}
7373

74-
/**
75-
* Holds if `c` happens in an exception-aware context, that is, it may be
76-
* `rescue`d or `ensure`d. In such cases, we assume that the target of `c`
77-
* may raise an exception (in addition to evaluating normally).
78-
*/
79-
private predicate mayRaise(Call c) {
80-
exists(Trees::BodyStmtTree bst | c = bst.getBodyChild(_, true).getAChild*() |
74+
private AstNode getARescuableBodyChild() {
75+
exists(Trees::BodyStmtTree bst | result = bst.getBodyChild(_, true) |
8176
exists(bst.getARescue())
8277
or
8378
exists(bst.getEnsure())
8479
)
80+
or
81+
result = getARescuableBodyChild().getAChild()
8582
}
8683

84+
/**
85+
* Holds if `c` happens in an exception-aware context, that is, it may be
86+
* `rescue`d or `ensure`d. In such cases, we assume that the target of `c`
87+
* may raise an exception (in addition to evaluating normally).
88+
*/
89+
private predicate mayRaise(Call c) { c = getARescuableBodyChild() }
90+
8791
/** A completion of a statement or an expression. */
8892
abstract class Completion extends TCompletion {
8993
private predicate isValidForSpecific(AstNode n) {

0 commit comments

Comments
 (0)