Commit Graph

70 Commits

Author SHA1 Message Date
Tom Hvitved
5ce9b25ec9 C#: Improve CFG for assignments
Write accesses in assignments, such as the access to `x` in `x = 0` are not
evaluated, so they should not have entries in the control flow graph. However,
qualifiers (and indexer arguments) should still be evaluated, for example in

```
x.Foo.Bar = 0;
```

the CFG should be `x --> x.Foo --> 0 --> x.Foo.Bar = 0` (as opposed to
`x --> x.Foo --> x.Foo.Bar --> 0 --> x.Foo.Bar = 0`, prior to this change).

A special case is assignments via acessors (properties, indexers, and event
adders), where we do want to include the access in the control flow graph,
as it represents the accessor call:

```
x.Prop = 0;
```

But instead of `x --> x.set_Prop --> 0 --> x.Prop = 0` the CFG should be
`x --> 0 --> x.set_Prop --> x.Prop = 0`, as the setter is called *after* the
assigned value has been evaluated.

An even more special case is tuple assignments via accessors:

```
(x.Prop1, y.Prop2) = (0, 1);
```

Here the CFG should be
`x --> y --> 0 --> 1 --> x.set_Prop1 --> y.set_Prop2 --> (x.Prop1, y.Prop2) = (0, 1)`.
2019-02-16 19:19:24 +01:00
Tom Hvitved
b4b6fdd12b C#: Revert recent change to AccessorCall
The recent change to `AccessorCall` on dd99525566 resulted
in some bad join-orders, so I have (partly) reverted them. This means that the issues
orignally addressed by that change are now reintroduced, and I plan to instead apply a
fix to the CFG, which--unlike the original fix--should be able to handle multi-property-tuple
assignments.
2019-02-04 15:14:18 +01:00
Tom Hvitved
dd99525566 C#: Redefine AccessorCall
The syntactic node assiociated with accessor calls was previously always the
underlying member access. For example, in

```
x.Prop = y.Prop;
```

the implicit call to `x.set_Prop()` was at the syntactic node `x.Prop`, while the
implicit call to `y.get_Prop()` was at the syntactic node `y.Prop`.

However, this breaks the invariant that arguments to calls dominate the call itself,
as the argument `y.Prop` for the implicit `value` parameter in `x.set_Prop()` will
be evaluated after the call (the left-hand side in an assignment is evaluated before
the right-hand side).

The solution is to redefine the access call to `x.set_Prop()` to point to the whole
assignment `x.Prop = y.Prop`, instead of the access `x.Prop`. For reads, we still want
to associate the accessor call with the member access.

A corner case arises when multiple setters are called in a tuple assignment:

```
(x.Prop1, x.Prop2) = (0, 1)
```

In this case, we cannot associate the assignment with both `x.set_Prop1()` and
`x.set_Prop2()`, so we instead revert to using the underlying member accesses as
before.
2019-01-18 13:56:23 +01:00
Tom Hvitved
2caf724826 C#: Add more tests 2019-01-18 12:07:22 +01:00
Tom Hvitved
33fcbc958d C#: Consider as expressions as maybe-null in cs/dereferenced-value-may-be-null 2018-12-20 14:54:48 +01:00
Tom Hvitved
ccda1c8d3d C#: Add nullness test using an as expression 2018-12-20 14:54:48 +01:00
Tom Hvitved
91e4f7ad83 C#: Make cs/dereferenced-value-may-be-null a path query 2018-12-14 12:07:16 +00:00
Tom Hvitved
e2f271bddb C#: Add more guard implication steps 2018-12-14 12:03:32 +00:00
Tom Hvitved
078dc7b6c0 C#: Fix false positives in cs/dereferenced-value-may-be-null 2018-12-14 12:03:32 +00:00
Tom Hvitved
287ce4e683 C#: Add more nullness tests 2018-12-14 12:03:32 +00:00
calum
3037b2b197 C#: Sync the -Good and -Bad files in the qltest to match the sample. 2018-12-12 11:36:00 +00:00
Tom Hvitved
fce805834e C#: Address review comments 2018-12-07 09:40:49 +01:00
Tom Hvitved
4739a6334e C#: Fix a bug and generalize guards implication logic 2018-12-03 15:33:00 +01:00
Tom Hvitved
3b0d1599ad C#: Teach guards library about unique assignments
For example, in

```
void M(object x)
{
    var y = x == null ? 1 : 2;
    if (y == 2)
        x.ToString();
}
```

the guard `y == 2` implies that the guard `x == null` must be false,
as the assignment of `2` to `y` is unique.
2018-11-30 17:43:10 +01:00
Tom Hvitved
ab9aa7d338 C#: Teach guards library about conditional assignments
For example, in

```
void M(object x)
{
    var y = x != null ? "" : null;
    if (y != null)
        x.ToString();
}
```

the guard `y != null` implies that the guard `x != null` must be true.
2018-11-30 17:41:36 +01:00
Tom Hvitved
80144a00c8 C#: Update nullness analyses
Port the SSA-based logic from the Java nullness analyses.
2018-11-30 17:41:31 +01:00
Tom Hvitved
d2a431e6f3 C#: Add more nullness tests
Port many of the nullness test from Java, as well as add new tests.
2018-11-30 17:02:05 +01:00
Tom Hvitved
5921a9ea51 C#: Teach guards library about assertions 2018-11-08 20:21:34 +01:00
Tom Hvitved
b233961a9a C#: Add assertion tests 2018-10-19 14:05:30 +02:00
Pavel Avgustinov
b55526aa58 QL code and tests for C#/C++/JavaScript. 2018-08-02 17:53:23 +01:00