Skip to content

Commit 0d81a64

Browse files
committed
SSA: Make shared library a parameterized module
1 parent f846c26 commit 0d81a64

File tree

6 files changed

+809
-718
lines changed

6 files changed

+809
-718
lines changed

csharp/ql/consistency-queries/SsaConsistency.ql

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import csharp
2-
import semmle.code.csharp.dataflow.internal.SsaImplCommon::Consistency
2+
import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency as Consistency
33
import Ssa
44

5-
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
5+
class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition {
66
override predicate hasLocationInfo(
77
string filepath, int startline, int startcolumn, int endline, int endcolumn
88
) {
99
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
1010
}
1111
}
1212

13+
query predicate nonUniqueDef = Consistency::nonUniqueDef/4;
14+
15+
query predicate readWithoutDef = Consistency::readWithoutDef/3;
16+
17+
query predicate deadDef = Consistency::deadDef/2;
18+
19+
query predicate notDominatedByDef = Consistency::notDominatedByDef/4;
20+
1321
query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) {
1422
// Local variables in C# must be initialized before every use, so uninitialized
1523
// local variables should not have an SSA definition, as that would imply that

csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ class BasicBlock extends TBasicBlockStart {
192192
* Gets the basic block that immediately dominates this basic block, if any.
193193
*
194194
* That is, all paths reaching this basic block from some entry point
195-
* basic block must go through the result, which is an immediate basic block
196-
* predecessor of this basic block.
195+
* basic block must go through the result.
197196
*
198197
* Example:
199198
*
@@ -207,8 +206,7 @@ class BasicBlock extends TBasicBlockStart {
207206
*
208207
* The basic block starting on line 2 is an immediate dominator of
209208
* the basic block online 4 (all paths from the entry point of `M`
210-
* to `return s.Length;` must go through the null check, and the null check
211-
* is an immediate predecessor of `return s.Length;`).
209+
* to `return s.Length;` must go through the null check.
212210
*/
213211
BasicBlock getImmediateDominator() { bbIDominates(result, this) }
214212

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,53 @@
33
*/
44

55
import csharp
6-
import SsaImplCommon
6+
private import SsaImplCommon as SsaImplCommon
7+
private import AssignableDefinitions
8+
9+
private module SsaInput implements SsaImplCommon::InputSig {
10+
class BasicBlock = ControlFlow::BasicBlock;
11+
12+
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
13+
14+
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
15+
16+
class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock;
17+
18+
class SourceVariable = Ssa::SourceVariable;
19+
20+
/**
21+
* Holds if the `i`th node of basic block `bb` is a (potential) write to source
22+
* variable `v`. The Boolean `certain` indicates whether the write is certain.
23+
*
24+
* This includes implicit writes via calls.
25+
*/
26+
predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
27+
variableWriteDirect(bb, i, v, certain)
28+
or
29+
variableWriteQualifier(bb, i, v, certain)
30+
or
31+
updatesNamedFieldOrProp(bb, i, _, v, _) and
32+
certain = false
33+
or
34+
updatesCapturedVariable(bb, i, _, v, _, _) and
35+
certain = false
36+
}
37+
38+
/**
39+
* Holds if the `i`th of basic block `bb` reads source variable `v`.
40+
*
41+
* This includes implicit reads via calls.
42+
*/
43+
predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
44+
variableReadActual(bb, i, v) and
45+
certain = true
46+
or
47+
variableReadPseudo(bb, i, v) and
48+
certain = false
49+
}
50+
}
51+
52+
import SsaImplCommon::Make<SsaInput>
753

854
/**
955
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
@@ -805,24 +851,6 @@ private module CapturedVariableImpl {
805851
}
806852
}
807853

808-
/**
809-
* Holds if the `i`th node of basic block `bb` is a (potential) write to source
810-
* variable `v`. The Boolean `certain` indicates whether the write is certain.
811-
*
812-
* This includes implicit writes via calls.
813-
*/
814-
predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
815-
variableWriteDirect(bb, i, v, certain)
816-
or
817-
variableWriteQualifier(bb, i, v, certain)
818-
or
819-
updatesNamedFieldOrProp(bb, i, _, v, _) and
820-
certain = false
821-
or
822-
updatesCapturedVariable(bb, i, _, v, _, _) and
823-
certain = false
824-
}
825-
826854
/**
827855
* Liveness analysis to restrict the size of the SSA representation for
828856
* captured variables.
@@ -1039,19 +1067,6 @@ private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::Sou
10391067
capturedReadIn(bb, i, v, _, _, _)
10401068
}
10411069

1042-
/**
1043-
* Holds if the `i`th of basic block `bb` reads source variable `v`.
1044-
*
1045-
* This includes implicit reads via calls.
1046-
*/
1047-
predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
1048-
variableReadActual(bb, i, v) and
1049-
certain = true
1050-
or
1051-
variableReadPseudo(bb, i, v) and
1052-
certain = false
1053-
}
1054-
10551070
cached
10561071
private module Cached {
10571072
cached
@@ -1151,7 +1166,7 @@ private module Cached {
11511166
predicate variableWriteQualifier(
11521167
ControlFlow::BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable v, boolean certain
11531168
) {
1154-
variableWrite(bb, i, v.getQualifier(), certain) and
1169+
SsaInput::variableWrite(bb, i, v.getQualifier(), certain) and
11551170
// Eliminate corner case where a call definition can overlap with a
11561171
// qualifier definition: if method `M` updates field `F`, then a call
11571172
// to `M` is both an update of `x.M` and `x.M.M`, so the former call

0 commit comments

Comments
 (0)