C#: Flow summaries should also apply for overides or virtual members in abstract classes.

This commit is contained in:
Michael Nebel
2021-12-13 10:36:55 +01:00
parent 7ff2ee695d
commit d699ca9aa8
3 changed files with 20 additions and 8 deletions

View File

@@ -362,14 +362,22 @@ class Virtualizable extends Member, @virtualizable {
/** Holds if this member implements (transitively) an interface member. */
predicate implements() { exists(this.getAnUltimateImplementee()) }
/**
* Holds if this member overrides or implements (transitively)
* `that` member.
*/
predicate overridesOrImplements(Virtualizable that) {
this.getOverridee+() = that or
this.getAnUltimateImplementee() = that
}
/**
* Holds if this member overrides or implements (reflexively, transitively)
* `that` member.
*/
predicate overridesOrImplementsOrEquals(Virtualizable that) {
this = that or
this.getOverridee+() = that or
this.getAnUltimateImplementee() = that
this.overridesOrImplements(that)
}
}

View File

@@ -13,8 +13,8 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
) {
this.propagatesFlow(input, output, preservesValue) and
not exists(IncludeSummarizedCallable rsc |
rsc.isAbstractOrInterface() and
this.(Virtualizable).overridesOrImplementsOrEquals(rsc) and
rsc.isBaseCallableOrPrototype() and
this.(Virtualizable).overridesOrImplements(rsc) and
rsc.propagatesFlow(input, output, preservesValue)
)
}

View File

@@ -16,14 +16,18 @@ abstract class IncludeSummarizedCallable extends RelevantSummarizedCallable {
)
}
predicate isAbstractOrInterface() {
this.getDeclaringType() instanceof Interface or
/** Holds if the summary should apply for all overrides of this. */
predicate isBaseCallableOrPrototype() {
this.getDeclaringType() instanceof Interface
or
this.(Modifiable).isAbstract()
or
this.getDeclaringType().(Modifiable).isAbstract() and this.(Virtualizable).isVirtual()
}
/** Gets a string representing, whether the declaring type is an interface. */
/** Gets a string representing, whether the summary should apply for all overrides of this. */
private string getCallableOverride() {
if this.isAbstractOrInterface() then result = "true" else result = "false"
if this.isBaseCallableOrPrototype() then result = "true" else result = "false"
}
/** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */