Skip to content

Commit d699ca9

Browse files
committed
C#: Flow summaries should also apply for overides or virtual members in abstract classes.
1 parent 7ff2ee6 commit d699ca9

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,14 +362,22 @@ class Virtualizable extends Member, @virtualizable {
362362
/** Holds if this member implements (transitively) an interface member. */
363363
predicate implements() { exists(this.getAnUltimateImplementee()) }
364364

365+
/**
366+
* Holds if this member overrides or implements (transitively)
367+
* `that` member.
368+
*/
369+
predicate overridesOrImplements(Virtualizable that) {
370+
this.getOverridee+() = that or
371+
this.getAnUltimateImplementee() = that
372+
}
373+
365374
/**
366375
* Holds if this member overrides or implements (reflexively, transitively)
367376
* `that` member.
368377
*/
369378
predicate overridesOrImplementsOrEquals(Virtualizable that) {
370379
this = that or
371-
this.getOverridee+() = that or
372-
this.getAnUltimateImplementee() = that
380+
this.overridesOrImplements(that)
373381
}
374382
}
375383

csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
1313
) {
1414
this.propagatesFlow(input, output, preservesValue) and
1515
not exists(IncludeSummarizedCallable rsc |
16-
rsc.isAbstractOrInterface() and
17-
this.(Virtualizable).overridesOrImplementsOrEquals(rsc) and
16+
rsc.isBaseCallableOrPrototype() and
17+
this.(Virtualizable).overridesOrImplements(rsc) and
1818
rsc.propagatesFlow(input, output, preservesValue)
1919
)
2020
}

csharp/ql/test/shared/FlowSummaries.qll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ abstract class IncludeSummarizedCallable extends RelevantSummarizedCallable {
1616
)
1717
}
1818

19-
predicate isAbstractOrInterface() {
20-
this.getDeclaringType() instanceof Interface or
19+
/** Holds if the summary should apply for all overrides of this. */
20+
predicate isBaseCallableOrPrototype() {
21+
this.getDeclaringType() instanceof Interface
22+
or
2123
this.(Modifiable).isAbstract()
24+
or
25+
this.getDeclaringType().(Modifiable).isAbstract() and this.(Virtualizable).isVirtual()
2226
}
2327

24-
/** Gets a string representing, whether the declaring type is an interface. */
28+
/** Gets a string representing, whether the summary should apply for all overrides of this. */
2529
private string getCallableOverride() {
26-
if this.isAbstractOrInterface() then result = "true" else result = "false"
30+
if this.isBaseCallableOrPrototype() then result = "true" else result = "false"
2731
}
2832

2933
/** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */

0 commit comments

Comments
 (0)