Skip to content

Commit bc4623e

Browse files
committed
C#: Define discarding predicates for expressions, statements, locations and some named TRAP entities.
1 parent 91c2d91 commit bc4623e

File tree

2 files changed

+228
-0
lines changed

2 files changed

+228
-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: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
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 UsingDirectiveEntity extends DiscardableEntity instanceof @using_directive {
91+
override string getPath() {
92+
exists(@location_default loc | using_directive_location(this, loc) |
93+
result = getLocationPath(loc)
94+
)
95+
}
96+
}
97+
98+
overlay[local]
99+
private class NamespaceDeclarationEntity extends DiscardableEntity instanceof @namespace_declaration
100+
{
101+
override string getPath() {
102+
exists(@location_default loc | namespace_declaration_location(this, loc) |
103+
result = getLocationPath(loc)
104+
)
105+
}
106+
}
107+
108+
overlay[local]
109+
private class PreprocessorDirectiveEntity extends DiscardableEntity instanceof @preprocessor_directive
110+
{
111+
override string getPath() {
112+
exists(@location_default loc | preprocessor_directive_location(this, loc) |
113+
result = getLocationPath(loc)
114+
)
115+
}
116+
}
117+
118+
overlay[local]
119+
private class TypeEntity extends DiscardableEntity instanceof @type {
120+
override string getPath() {
121+
exists(@location_default loc | type_location(this, loc) | result = getLocationPath(loc))
122+
}
123+
}
124+
125+
overlay[local]
126+
private class AttributeEntity extends DiscardableEntity instanceof @attribute {
127+
override string getPath() {
128+
exists(@location_default loc | attribute_location(this, loc) | result = getLocationPath(loc))
129+
}
130+
}
131+
132+
overlay[local]
133+
private class TypeParameterConstraintsEntity extends DiscardableEntity instanceof @type_parameter_constraints
134+
{
135+
override string getPath() {
136+
exists(@location_default loc | type_parameter_constraints_location(this, loc) |
137+
result = getLocationPath(loc)
138+
)
139+
}
140+
}
141+
142+
overlay[local]
143+
private class PropertyEntity extends DiscardableEntity instanceof @property {
144+
override string getPath() {
145+
exists(@location_default loc | property_location(this, loc) | result = getLocationPath(loc))
146+
}
147+
}
148+
149+
overlay[local]
150+
private class IndexerEntity extends DiscardableEntity instanceof @indexer {
151+
override string getPath() {
152+
exists(@location_default loc | indexer_location(this, loc) | result = getLocationPath(loc))
153+
}
154+
}
155+
156+
overlay[local]
157+
private class AccessorEntity extends DiscardableEntity instanceof @accessor {
158+
override string getPath() {
159+
exists(@location_default loc | accessor_location(this, loc) | result = getLocationPath(loc))
160+
}
161+
}
162+
163+
overlay[local]
164+
private class EventEntity extends DiscardableEntity instanceof @event {
165+
override string getPath() {
166+
exists(@location_default loc | event_location(this, loc) | result = getLocationPath(loc))
167+
}
168+
}
169+
170+
overlay[local]
171+
private class EventAccessorEntity extends DiscardableEntity instanceof @event_accessor {
172+
override string getPath() {
173+
exists(@location_default loc | event_accessor_location(this, loc) |
174+
result = getLocationPath(loc)
175+
)
176+
}
177+
}
178+
179+
overlay[local]
180+
private class OperatorEntity extends DiscardableEntity instanceof @operator {
181+
override string getPath() {
182+
exists(@location_default loc | operator_location(this, loc) | result = getLocationPath(loc))
183+
}
184+
}
185+
186+
overlay[local]
187+
private class MethodEntity extends DiscardableEntity instanceof @method {
188+
override string getPath() {
189+
exists(@location_default loc | method_location(this, loc) | result = getLocationPath(loc))
190+
}
191+
}
192+
193+
overlay[local]
194+
private class ConstructorEntity extends DiscardableEntity instanceof @constructor {
195+
override string getPath() {
196+
exists(@location_default loc | constructor_location(this, loc) | result = getLocationPath(loc))
197+
}
198+
}
199+
200+
overlay[local]
201+
private class DestructorEntity extends DiscardableEntity instanceof @destructor {
202+
override string getPath() {
203+
exists(@location_default loc | destructor_location(this, loc) | result = getLocationPath(loc))
204+
}
205+
}
206+
207+
overlay[local]
208+
private class FieldEntity extends DiscardableEntity instanceof @field {
209+
override string getPath() {
210+
exists(@location_default loc | field_location(this, loc) | result = getLocationPath(loc))
211+
}
212+
}
213+
214+
overlay[local]
215+
private class LocalVariableEntity extends DiscardableEntity instanceof @local_variable {
216+
override string getPath() {
217+
exists(@location_default loc | localvar_location(this, loc) | result = getLocationPath(loc))
218+
}
219+
}
220+
221+
overlay[local]
222+
private class ParameterEntity extends DiscardableEntity instanceof @parameter {
223+
override string getPath() {
224+
exists(@location_default loc | param_location(this, loc) | result = getLocationPath(loc))
225+
}
226+
}
227+
// TODO: We Still need to handle commentline, comment block entities and type mentions.

0 commit comments

Comments
 (0)