From 17193ac11b36d584cb7770f549e4a42bf6169bed Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 25 Mar 2024 16:20:36 +0000 Subject: [PATCH] Distinguish record patterns that do or don't declare identifiers --- java/ql/lib/semmle/code/java/Expr.qll | 10 ++++++++++ .../code/java/dataflow/internal/DataFlowUtil.qll | 15 +++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index b9b535eb57c..e0208b4df9e 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -2739,4 +2739,14 @@ class RecordPatternExpr extends Expr, @recordpatternexpr { ) ) } + + /** + * Holds if this record pattern declares any identifiers (i.e., at least one leaf declaration is named). + */ + predicate declaresAnyIdentifiers() { + exists(PatternExpr subPattern | subPattern = this.getSubPattern(_) | + subPattern.asRecordPattern().declaresAnyIdentifiers() or + not subPattern.asBindingOrUnnamedPattern().isAnonymous() + ) + } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 95faf4fbabc..c40520c3500 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -194,14 +194,17 @@ predicate simpleAstFlowStep(Expr e1, Expr e2) { // In the following three cases only record patterns need this flow edge, leading from the bound instanceof // or switch tested expression to a record pattern that will read its fields. Simple binding patterns are // handled via VariableAssign.getSource instead. - // We only consider unique patterns because cases that declare multiple patterns are not allowed to declare - // any identifiers, so can't participate in dataflow. - exists(SwitchExpr se | - e1 = se.getExpr() and e2 = se.getACase().(PatternCase).getUniquePattern().asRecordPattern() + // We only consider patterns that declare any identifiers + exists(SwitchExpr se, RecordPatternExpr recordPattern | recordPattern = e2 | + e1 = se.getExpr() and + recordPattern = se.getACase().(PatternCase).getAPattern() and + recordPattern.declaresAnyIdentifiers() ) or - exists(SwitchStmt ss | - e1 = ss.getExpr() and e2 = ss.getACase().(PatternCase).getUniquePattern().asRecordPattern() + exists(SwitchStmt ss, RecordPatternExpr recordPattern | recordPattern = e2 | + e1 = ss.getExpr() and + recordPattern = ss.getACase().(PatternCase).getAPattern() and + recordPattern.declaresAnyIdentifiers() ) or exists(InstanceOfExpr ioe | e1 = ioe.getExpr() and e2 = ioe.getPattern().asRecordPattern())