Address review comments

This commit is contained in:
Tom Hvitved
2020-06-19 10:34:11 +02:00
parent 9e7ca25732
commit ca86bb8603
4 changed files with 95 additions and 61 deletions

View File

@@ -685,7 +685,7 @@ module Unification {
private import Cached
/**
* Holds if types `t1` and `t2` are unifiable. That is, is it possible to replace
* Holds if types `t1` and `t2` are unifiable. That is, it is possible to replace
* all type parameters in `t1` and `t2` with some (other) types to make the two
* substituted terms equal.
*
@@ -722,7 +722,7 @@ module Unification {
}
/**
* Holds if type `t1` subsumes type `t2`. That is, is it possible to replace all
* Holds if type `t1` subsumes type `t2`. That is, it is possible to replace all
* type parameters in `t1` with some (other) types to make the two types equal.
*
* The same limitations that apply to the predicate `unifiable()` apply to this

View File

@@ -265,12 +265,13 @@ private module Internal {
private predicate hasQualifierTypeOverridden0(ValueOrRefType t, DispatchMethodOrAccessorCall call) {
hasOverrider(_, t) and
(
exists(Type t0 | t0 = getAPossibleType(call.getQualifier(), false) |
t = t0
exists(Type t0, Type t1 |
t0 = getAPossibleType(call.getQualifier(), false) and
t1 = [t0, t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()]
|
t = t1
or
Unification::subsumes(t0, t)
or
t = t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()
Unification::subsumes(t1, t)
)
or
constrainedTypeParameterQualifierTypeSubsumes(t,
@@ -325,7 +326,8 @@ private module Internal {
/**
* Holds if the call `ctx` might act as a context that improves the set of
* dispatch targets of this call, which occurs in a viable target of `ctx`.
* dispatch targets of this call, depending on the type of the `i`th argument
* of `ctx`.
*/
pragma[nomagic]
private predicate relevantContext(DispatchCall ctx, int i) {
@@ -333,7 +335,8 @@ private module Internal {
}
/**
* Holds if the `i`th argument of `ctx` has type `t` and `ctx` is a relevant
* Holds if the argument of `ctx`, which is passed for the parameter that is
* accessed in the qualifier of this call, has type `t` and `ctx` is a relevant
* call context.
*/
private predicate contextArgHasType(DispatchCall ctx, Type t, boolean isExact) {
@@ -377,25 +380,29 @@ private module Internal {
* Example:
*
* ```csharp
* class A {
* public virtual void M() { }
* class A
* {
* public virtual void M() { }
* }
*
* class B : A {
* public override void M() { }
* class B : A
* {
* public override void M() { }
* }
*
* class C : B { }
*
* class D {
* void CallM() {
* A x = new A();
* x.M();
* x = new B();
* x.M();
* x = new C();
* x.M();
* }
* class D
* {
* void CallM()
* {
* A x = new A();
* x.M();
* x = new B();
* x.M();
* x = new C();
* x.M();
* }
* }
* ```
*
@@ -421,27 +428,32 @@ private module Internal {
* Example:
*
* ```csharp
* class A {
* public virtual void M() { }
* class A
* {
* public virtual void M() { }
* }
*
* class B : A {
* public override void M() { }
* class B : A
* {
* public override void M() { }
* }
*
* class C : B {
* public override void M() { }
* class C : B
* {
* public override void M() { }
* }
*
* class D {
* void CallM() {
* A x = new A();
* x.M();
* x = new B();
* x.M();
* x = new C();
* x.M();
* }
* class D
* {
* void CallM()
* {
* A x = new A();
* x.M();
* x = new B();
* x.M();
* x = new C();
* x.M();
* }
* }
* ```
*
@@ -507,12 +519,13 @@ private module Internal {
) {
exists(ValueOrRefType t |
result = this.getAViableOverriderInCallContext0(c, t) and
exists(Type t0 | this.contextArgHasType(ctx, t0, false) |
t = t0
exists(Type t0, Type t1 |
this.contextArgHasType(ctx, t0, false) and
t1 = [t0, t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()]
|
t = t1
or
Unification::subsumes(t0, t)
or
t = t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()
Unification::subsumes(t1, t)
)
)
}
@@ -764,22 +777,25 @@ private module Internal {
* For reflection/dynamic calls, unless the type of the qualifier is exact,
* all subtypes of the qualifier type must be considered relevant. Example:
*
* ```
* class A {
* public void M() { Console.WriteLine("A"); }
* ```csharp
* class A
* {
* public void M() { Console.WriteLine("A"); }
* }
*
* class B : A {
* new public void M() { Console.WriteLine("B"); }
* class B : A
* {
* new public void M() { Console.WriteLine("B"); }
* }
*
* class C {
* void InvokeMDyn(A x) { ((dynamic) x).M(); }
* class C
* {
* void InvokeMDyn(A x) { ((dynamic) x).M(); }
*
* void CallM() {
* InvokeMDyn(new A()); // prints "A"
* InvokeMDyn(new B()); // prints "B"
* }
* void CallM() {
* InvokeMDyn(new A()); // prints "A"
* InvokeMDyn(new B()); // prints "B"
* }
* }
* ```
*

View File

@@ -163,7 +163,12 @@ public class A2
public virtual void M(object o)
{
Sink(o); // no flow here
Sink(o);
}
public static void CallM(A2 a2, object o)
{
a2.M(o);
}
public void Callsite(InterfaceB intF)
@@ -172,7 +177,10 @@ public class A2
// in both possible implementations of foo, this callsite is relevant
// in IntA, it improves virtual dispatch,
// and in IntB, it improves the dataflow analysis.
intF.Foo(b, new object(), false);
intF.Foo(b, new object(), false); // no flow to `Sink()` via `A2.M()`, but flow via `IntA.Foo()`
CallM(b, new object()); // no flow to `Sink()`
CallM(this, new object()); // flow to `Sink()`
}
public class B : A2

View File

@@ -26,8 +26,12 @@ edges
| CallSensitivityFlow.cs:124:43:124:43 | o : Object | CallSensitivityFlow.cs:128:22:128:22 | access to parameter o |
| CallSensitivityFlow.cs:133:44:133:44 | o : Object | CallSensitivityFlow.cs:137:22:137:22 | access to parameter o |
| CallSensitivityFlow.cs:142:49:142:49 | o : Object | CallSensitivityFlow.cs:152:18:152:19 | access to local variable o3 |
| CallSensitivityFlow.cs:175:21:175:32 | object creation of type Object : Object | CallSensitivityFlow.cs:189:40:189:40 | o : Object |
| CallSensitivityFlow.cs:189:40:189:40 | o : Object | CallSensitivityFlow.cs:192:18:192:18 | access to parameter o |
| CallSensitivityFlow.cs:164:34:164:34 | o : Object | CallSensitivityFlow.cs:166:14:166:14 | access to parameter o |
| CallSensitivityFlow.cs:169:44:169:44 | o : Object | CallSensitivityFlow.cs:171:14:171:14 | access to parameter o : Object |
| CallSensitivityFlow.cs:171:14:171:14 | access to parameter o : Object | CallSensitivityFlow.cs:164:34:164:34 | o : Object |
| CallSensitivityFlow.cs:180:21:180:32 | object creation of type Object : Object | CallSensitivityFlow.cs:197:40:197:40 | o : Object |
| CallSensitivityFlow.cs:183:21:183:32 | object creation of type Object : Object | CallSensitivityFlow.cs:169:44:169:44 | o : Object |
| CallSensitivityFlow.cs:197:40:197:40 | o : Object | CallSensitivityFlow.cs:200:18:200:18 | access to parameter o |
nodes
| CallSensitivityFlow.cs:19:39:19:39 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | semmle.label | access to parameter o |
@@ -66,9 +70,14 @@ nodes
| CallSensitivityFlow.cs:137:22:137:22 | access to parameter o | semmle.label | access to parameter o |
| CallSensitivityFlow.cs:142:49:142:49 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:152:18:152:19 | access to local variable o3 | semmle.label | access to local variable o3 |
| CallSensitivityFlow.cs:175:21:175:32 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| CallSensitivityFlow.cs:189:40:189:40 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:192:18:192:18 | access to parameter o | semmle.label | access to parameter o |
| CallSensitivityFlow.cs:164:34:164:34 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:166:14:166:14 | access to parameter o | semmle.label | access to parameter o |
| CallSensitivityFlow.cs:169:44:169:44 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:171:14:171:14 | access to parameter o : Object | semmle.label | access to parameter o : Object |
| CallSensitivityFlow.cs:180:21:180:32 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| CallSensitivityFlow.cs:183:21:183:32 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| CallSensitivityFlow.cs:197:40:197:40 | o : Object | semmle.label | o : Object |
| CallSensitivityFlow.cs:200:18:200:18 | access to parameter o | semmle.label | access to parameter o |
#select
| CallSensitivityFlow.cs:78:24:78:35 | object creation of type Object : Object | CallSensitivityFlow.cs:78:24:78:35 | object creation of type Object : Object | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | $@ | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | access to parameter o |
| CallSensitivityFlow.cs:79:25:79:36 | object creation of type Object : Object | CallSensitivityFlow.cs:79:25:79:36 | object creation of type Object : Object | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | $@ | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | access to parameter o |
@@ -87,4 +96,5 @@ nodes
| CallSensitivityFlow.cs:117:26:117:37 | object creation of type Object : Object | CallSensitivityFlow.cs:117:26:117:37 | object creation of type Object : Object | CallSensitivityFlow.cs:128:22:128:22 | access to parameter o | $@ | CallSensitivityFlow.cs:128:22:128:22 | access to parameter o | access to parameter o |
| CallSensitivityFlow.cs:118:27:118:38 | object creation of type Object : Object | CallSensitivityFlow.cs:118:27:118:38 | object creation of type Object : Object | CallSensitivityFlow.cs:137:22:137:22 | access to parameter o | $@ | CallSensitivityFlow.cs:137:22:137:22 | access to parameter o | access to parameter o |
| CallSensitivityFlow.cs:119:32:119:43 | object creation of type Object : Object | CallSensitivityFlow.cs:119:32:119:43 | object creation of type Object : Object | CallSensitivityFlow.cs:152:18:152:19 | access to local variable o3 | $@ | CallSensitivityFlow.cs:152:18:152:19 | access to local variable o3 | access to local variable o3 |
| CallSensitivityFlow.cs:175:21:175:32 | object creation of type Object : Object | CallSensitivityFlow.cs:175:21:175:32 | object creation of type Object : Object | CallSensitivityFlow.cs:192:18:192:18 | access to parameter o | $@ | CallSensitivityFlow.cs:192:18:192:18 | access to parameter o | access to parameter o |
| CallSensitivityFlow.cs:180:21:180:32 | object creation of type Object : Object | CallSensitivityFlow.cs:180:21:180:32 | object creation of type Object : Object | CallSensitivityFlow.cs:200:18:200:18 | access to parameter o | $@ | CallSensitivityFlow.cs:200:18:200:18 | access to parameter o | access to parameter o |
| CallSensitivityFlow.cs:183:21:183:32 | object creation of type Object : Object | CallSensitivityFlow.cs:183:21:183:32 | object creation of type Object : Object | CallSensitivityFlow.cs:166:14:166:14 | access to parameter o | $@ | CallSensitivityFlow.cs:166:14:166:14 | access to parameter o | access to parameter o |