From c4c936d6fa06009a817cc0d18f86d9de67934aab Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Oct 2024 15:20:54 +0200 Subject: [PATCH] Rust: Speedup `SummaryStats.ql` --- rust/ql/lib/codeql/rust/AstConsistency.qll | 24 ++++++++++++------- .../controlflow/internal/CfgConsistency.qll | 18 ++++++++------ shared/controlflow/codeql/controlflow/Cfg.qll | 7 ++++-- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/rust/ql/lib/codeql/rust/AstConsistency.qll b/rust/ql/lib/codeql/rust/AstConsistency.qll index 525726999aab..f586080ab59b 100644 --- a/rust/ql/lib/codeql/rust/AstConsistency.qll +++ b/rust/ql/lib/codeql/rust/AstConsistency.qll @@ -5,12 +5,14 @@ private import rust private import codeql.rust.elements.internal.generated.ParentChild +private predicate multipleToStrings(Element e) { strictcount(e.toString()) > 1 } + /** * Holds if `e` has more than one `toString()` result. */ query predicate multipleToStrings(Element e, string s) { - s = strictconcat(e.toString(), ", ") and - strictcount(e.toString()) > 1 + multipleToStrings(e) and + s = strictconcat(e.toString(), ", ") } /** @@ -18,22 +20,26 @@ query predicate multipleToStrings(Element e, string s) { */ query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 } +private predicate multiplePrimaryQlClasses(Element e) { strictcount(e.getAPrimaryQlClass()) > 1 } + /** * Holds if `e` has more than one `getPrimaryQlClasses()` result. */ query predicate multiplePrimaryQlClasses(Element e, string s) { - s = strictconcat(e.getPrimaryQlClasses(), ", ") and - strictcount(e.getAPrimaryQlClass()) > 1 + multiplePrimaryQlClasses(e) and + s = strictconcat(e.getPrimaryQlClasses(), ", ") } private Element getParent(Element child) { child = getChildAndAccessor(result, _, _) } +private predicate multipleParents(Element child) { strictcount(getParent(child)) > 1 } + /** * Holds if `child` has more than one AST parent. */ query predicate multipleParents(Element child, Element parent) { - parent = getParent(child) and - strictcount(getParent(child)) > 1 + multipleParents(child) and + parent = getParent(child) } /** @@ -42,14 +48,14 @@ query predicate multipleParents(Element child, Element parent) { int getAstInconsistencyCounts(string type) { // total results from all the AST consistency query predicates. type = "Multiple toStrings" and - result = count(Element e | multipleToStrings(e, _) | e) + result = count(Element e | multipleToStrings(e) | e) or type = "Multiple locations" and result = count(Element e | multipleLocations(e) | e) or type = "Multiple primary QL classes" and - result = count(Element e | multiplePrimaryQlClasses(e, _) | e) + result = count(Element e | multiplePrimaryQlClasses(e) | e) or type = "Multiple parents" and - result = count(Element e | multipleParents(e, _) | e) + result = count(Element e | multipleParents(e) | e) } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll index 378062e16b41..668533f1c3dd 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll @@ -9,11 +9,7 @@ private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as CfgImpl private import codeql.rust.controlflow.internal.Completion -/** - * All `Expr` nodes are `PostOrderTree`s - */ -query predicate nonPostOrderExpr(Expr e, string cls) { - cls = e.getPrimaryQlClasses() and +private predicate nonPostOrderExpr(Expr e) { not e instanceof LetExpr and not e instanceof ParenExpr and exists(AstNode last, Completion c | @@ -23,6 +19,14 @@ query predicate nonPostOrderExpr(Expr e, string cls) { ) } +/** + * All `Expr` nodes are `PostOrderTree`s + */ +query predicate nonPostOrderExpr(Expr e, string cls) { + nonPostOrderExpr(e) and + cls = e.getPrimaryQlClasses() +} + /** * Holds if CFG scope `scope` lacks an initial AST node. Overrides shared consistency predicate. */ @@ -84,11 +88,11 @@ int getCfgInconsistencyCounts(string type) { result = count(CfgImpl::SplitKind sk | nonUniqueListOrder(sk, _) | sk) or type = "Multiple toStrings" and - result = count(CfgNode n | multipleToString(n, _) | n) + result = count(CfgNode n | multipleToString(n) | n) or type = "CFG scope lacks initial AST node" and result = count(CfgScope s | scopeNoFirst(s) | s) or type = "Non-PostOrderTree Expr node" and - result = count(Expr e | nonPostOrderExpr(e, _) | e) + result = count(Expr e | nonPostOrderExpr(e) | e) } diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index be05a5695a95..4130920daf67 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1502,10 +1502,13 @@ module MakeWithSplitting< strictcount(sk.getListOrder()) > 1 } + /** Holds if `n` has multiple textual representations. */ + predicate multipleToString(Node n) { strictcount(n.toString()) > 1 } + /** Holds if `n` has multiple textual representations. */ query predicate multipleToString(Node n, string s) { - s = strictconcat(n.toString(), ",") and - strictcount(n.toString()) > 1 + multipleToString(n) and + s = strictconcat(n.toString(), ",") } /** Holds if CFG scope `scope` lacks an initial AST node. */