Skip to content

Commit 16270cf

Browse files
committed
C#: Add configuration class to allow defining a candidate pairs of control flow predicates, where we want to look for structural equality.
1 parent 87cb92a commit 16270cf

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,44 @@ Gvn toGvn(ControlFlowElement cfe) {
194194
result = TListGvn(l)
195195
)
196196
}
197+
198+
/**
199+
* A configuration for performing structural comparisons of program elements
200+
* (expressions and statements).
201+
*
202+
* The predicate `candidate()` must be overridden, in order to identify the
203+
* elements for which to perform structural comparison.
204+
*
205+
* Each use of the library is identified by a unique string value.
206+
*/
207+
abstract class StructuralComparisonConfiguration extends string {
208+
bindingset[this]
209+
StructuralComparisonConfiguration() { any() }
210+
211+
/**
212+
* Holds if elements `x` and `y` are candidates for testing structural
213+
* equality.
214+
*
215+
* Subclasses are expected to override this predicate to identify the
216+
* top-level elements which they want to compare. Care should be
217+
* taken to avoid identifying too many pairs of elements, as in general
218+
* there are very many structurally equal subtrees in a program, and
219+
* in order to keep the computation feasible we must focus attention.
220+
*
221+
* Note that this relation is not expected to be symmetric -- it's
222+
* fine to include a pair `(x, y)` but not `(y, x)`.
223+
* In fact, not including the symmetrically implied fact will save
224+
* half the computation time on the structural comparison.
225+
*/
226+
abstract predicate candidate(ControlFlowElement x, ControlFlowElement y);
227+
228+
/**
229+
* Holds if elements `x` and `y` structurally equal. `x` and `y` must be
230+
* flagged as candidates for structural equality, that is,
231+
* `candidate(x, y)` must hold.
232+
*/
233+
predicate same(ControlFlowElement x, ControlFlowElement y) {
234+
candidate(x, y) and
235+
toGvn(x) = toGvn(y)
236+
}
237+
}

0 commit comments

Comments
 (0)