From f634b328eeba3ea359dc52b1d570f458182fc875 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 28 Apr 2026 15:44:53 +0200 Subject: [PATCH] C++: Fix join-order problem in `getNextSwitchCase` Before on `neovim`: ``` [2026-04-28 14:54:20] Evaluated non-recursive predicate Stmt::SwitchCase.getNextSwitchCase/0#dispred#2d3cb6d3@ac8178o2 in 68ms (size: 20848). Evaluated relational algebra for predicate Stmt::SwitchCase.getNextSwitchCase/0#dispred#2d3cb6d3@ac8178o2 with tuple counts: 21888 ~0% {2} r1 = SCAN switch_case OUTPUT In.2, In.0 21888 ~0% {4} | JOIN WITH #switch_caseMerge_21#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.0, _, Rhs.1 21888 ~4% {3} | REWRITE WITH Tmp.2 := 1, Out.2 := (In.3 - Tmp.2) KEEPING 3 24091916 ~0% {3} | JOIN WITH switch_case ON FIRST 1 OUTPUT Lhs.2, Rhs.2, Lhs.1 20848 ~2% {2} | JOIN WITH #switch_caseMerge_12#join_rhs ON FIRST 2 OUTPUT Lhs.1, Lhs.2 return r1 ``` After: ``` [2026-04-28 15:30:53] Evaluated non-recursive predicate Stmt::SwitchCase.getNextSwitchCase/0#dispred#2d3cb6d3@bf9801oj in 0ms (size: 20848). Evaluated relational algebra for predicate Stmt::SwitchCase.getNextSwitchCase/0#dispred#2d3cb6d3@bf9801oj with tuple counts: 21888 ~0% {4} r1 = SCAN switch_case OUTPUT In.0, _, In.2, In.1 21888 ~1% {3} | REWRITE WITH Tmp.1 := 1, Out.1 := (In.3 + Tmp.1) KEEPING 3 20848 ~2% {2} | JOIN WITH switch_case ON FIRST 2 OUTPUT Lhs.2, Rhs.2 return r1 ``` --- cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll index c974353bc7a..b7905a9d23f 100644 --- a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll @@ -1516,8 +1516,10 @@ class SwitchCase extends Stmt, @stmt_switch_case { * which has result `default:`, which has no result. */ SwitchCase getNextSwitchCase() { - result.getSwitchStmt() = this.getSwitchStmt() and - result.getChildNum() = this.getChildNum() + 1 + exists(SwitchStmt s, int n | + this = s.getSwitchCase(n) and + result = s.getSwitchCase(n + 1) + ) } /**