Skip to content

Commit 871c6c9

Browse files
committed
C#: Define discarding predicates for expressions, statements, locations and some named TRAP entities.
1 parent ae2374c commit 871c6c9

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

csharp/ql/lib/csharp.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import semmle.code.csharp.controlflow.ControlFlowGraph
3636
import semmle.code.csharp.dataflow.DataFlow
3737
import semmle.code.csharp.dataflow.TaintTracking
3838
import semmle.code.csharp.dataflow.SSA
39+
private import semmle.code.csharp.Overlay
3940

4041
/** Whether the source was extracted without a build command. */
4142
predicate extractionIsStandalone() { exists(SourceFile f | f.extractedStandalone()) }
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Defines entity discard predicates for C# overlay analysis.
3+
*/
4+
5+
/**
6+
* Holds always for the overlay variant and never for the base variant.
7+
* This local predicate is used to define local predicates that behave
8+
* differently for the base and overlay variant.
9+
*/
10+
overlay[local]
11+
predicate isOverlay() { databaseMetadata("isOverlay", "true") }
12+
13+
/**
14+
* An abstract base class for all elements that can be discarded from the base.
15+
*/
16+
overlay[local]
17+
abstract private class DiscardableEntity extends @element {
18+
/** Gets the path to the file in which this element occurs. */
19+
abstract string getPath();
20+
21+
/** Holds if this element exists in the base variant. */
22+
predicate existsInBase() { not isOverlay() and exists(this) }
23+
24+
/** Holds if this element exists in the overlay variant. */
25+
predicate existsInOverlay() { isOverlay() and exists(this) }
26+
27+
/** Gets a textual representation of this discardable element. */
28+
string toString() { none() }
29+
}
30+
31+
/**
32+
* A class of C# database entities that use `*` IDs.
33+
* The rest use named TRAP IDs.
34+
*/
35+
overlay[local]
36+
private class StarEntity = @expr or @stmt;
37+
38+
overlay[discard_entity]
39+
private predicate discardStarEntity(@element e) {
40+
e instanceof StarEntity and
41+
// Entities with *-ids can exist either in base or overlay, but not both.
42+
exists(DiscardableEntity de | de = e |
43+
overlayChangedFiles(de.getPath()) and
44+
de.existsInBase()
45+
)
46+
}
47+
48+
overlay[discard_entity]
49+
private predicate discardNamedEntity(@element e) {
50+
not e instanceof StarEntity and
51+
// Entities with named IDs can exist both in base, overlay, or both.
52+
exists(DiscardableEntity de | de = e |
53+
overlayChangedFiles(de.getPath()) and
54+
not de.existsInOverlay()
55+
)
56+
}
57+
58+
overlay[local]
59+
private string getLocationPath(@location_default loc) {
60+
exists(@file file | locations_default(loc, file, _, _, _, _) | files(file, result))
61+
}
62+
63+
overlay[local]
64+
private predicate discardableLocation(@location_default loc, string path) {
65+
not isOverlay() and
66+
path = getLocationPath(loc)
67+
}
68+
69+
// Discard locations that are in changed files from the base variant.
70+
overlay[discard_entity]
71+
private predicate discardLocation(@location_default loc) {
72+
exists(string path | discardableLocation(loc, path) | overlayChangedFiles(path))
73+
}
74+
75+
overlay[local]
76+
private class ExprEntity extends DiscardableEntity instanceof @expr {
77+
override string getPath() {
78+
exists(@location_default loc | expr_location(this, loc) | result = getLocationPath(loc))
79+
}
80+
}
81+
82+
overlay[local]
83+
private class StmtEntity extends DiscardableEntity instanceof @stmt {
84+
override string getPath() {
85+
exists(@location_default loc | stmt_location(this, loc) | result = getLocationPath(loc))
86+
}
87+
}
88+
89+
overlay[local]
90+
private class TypeEntity extends DiscardableEntity instanceof @type {
91+
override string getPath() {
92+
exists(@location_default loc | type_location(this, loc) | result = getLocationPath(loc))
93+
}
94+
}
95+
96+
overlay[local]
97+
private class MethodEntity extends DiscardableEntity instanceof @method {
98+
override string getPath() {
99+
exists(@location_default loc | method_location(this, loc) | result = getLocationPath(loc))
100+
}
101+
}

0 commit comments

Comments
 (0)