From 780ea72b3b43105ee080f8c9a7819728c3c1b2de Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 2 Nov 2022 09:11:45 +0100 Subject: [PATCH] Revert "SSA: Turn consistency predicates into `query` predicates" --- .../ql/consistency-queries/SsaConsistency.ql | 12 +++++++++-- ruby/ql/consistency-queries/SsaConsistency.ql | 12 +++++++++-- shared/ssa/codeql/ssa/Ssa.qll | 20 ++++++++----------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/csharp/ql/consistency-queries/SsaConsistency.ql b/csharp/ql/consistency-queries/SsaConsistency.ql index bd666a71e493..71f88bf2ab05 100644 --- a/csharp/ql/consistency-queries/SsaConsistency.ql +++ b/csharp/ql/consistency-queries/SsaConsistency.ql @@ -1,8 +1,8 @@ import csharp -import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency +import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency as Consistency import Ssa -class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { +class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { @@ -10,6 +10,14 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { } } +query predicate nonUniqueDef = Consistency::nonUniqueDef/4; + +query predicate readWithoutDef = Consistency::readWithoutDef/3; + +query predicate deadDef = Consistency::deadDef/2; + +query predicate notDominatedByDef = Consistency::notDominatedByDef/4; + query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) { // Local variables in C# must be initialized before every use, so uninitialized // local variables should not have an SSA definition, as that would imply that diff --git a/ruby/ql/consistency-queries/SsaConsistency.ql b/ruby/ql/consistency-queries/SsaConsistency.ql index 7ba9262baa4c..54c1b149ab24 100644 --- a/ruby/ql/consistency-queries/SsaConsistency.ql +++ b/ruby/ql/consistency-queries/SsaConsistency.ql @@ -1,10 +1,18 @@ import codeql.ruby.dataflow.SSA -import codeql.ruby.dataflow.internal.SsaImpl::Consistency +import codeql.ruby.dataflow.internal.SsaImpl::Consistency as Consistency -class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition { +class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition { override predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } } + +query predicate nonUniqueDef = Consistency::nonUniqueDef/4; + +query predicate readWithoutDef = Consistency::readWithoutDef/3; + +query predicate deadDef = Consistency::deadDef/2; + +query predicate notDominatedByDef = Consistency::notDominatedByDef/4; diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index 19f31f7c8bbe..886e4128e262 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -9,10 +9,7 @@ signature module InputSig { * A basic block, that is, a maximal straight-line sequence of control flow nodes * without branches or joins. */ - class BasicBlock { - /** Gets a textual representation of this basic block. */ - string toString(); - } + class BasicBlock; /** * Gets the basic block that immediately dominates basic block `bb`, if any. @@ -46,10 +43,7 @@ signature module InputSig { class ExitBasicBlock extends BasicBlock; /** A variable that can be SSA converted. */ - class SourceVariable { - /** Gets a textual representation of this variable. */ - string toString(); - } + class SourceVariable; /** * Holds if the `i`th node of basic block `bb` is a (potential) write to source @@ -852,6 +846,8 @@ module Make { } /** Provides a set of consistency queries. */ + // TODO: Make these `query` predicates once class signatures are supported + // (`SourceVariable` and `BasicBlock` must have `toString`) module Consistency { /** A definition that is relevant for the consistency queries. */ abstract class RelevantDefinition extends Definition { @@ -862,19 +858,19 @@ module Make { } /** Holds if a read can be reached from multiple definitions. */ - query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { + predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { ssaDefReachesRead(v, def, bb, i) and not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i))) } /** Holds if a read cannot be reached from a definition. */ - query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) { + predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) { variableRead(bb, i, v, _) and not ssaDefReachesRead(v, _, bb, i) } /** Holds if a definition cannot reach a read. */ - query predicate deadDef(RelevantDefinition def, SourceVariable v) { + predicate deadDef(RelevantDefinition def, SourceVariable v) { v = def.getSourceVariable() and not ssaDefReachesRead(_, def, _, _) and not phiHasInputFromBlock(_, def, _) and @@ -882,7 +878,7 @@ module Make { } /** Holds if a read is not dominated by a definition. */ - query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { + predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) { exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) | ssaDefReachesReadWithinBlock(v, def, bb, i) and (bb != bbDef or i < iDef)