Roslyn doesn't adjust annotations for members with outputs stricter than inputs in object initializers leading to false positive possible null dereferences #49028
Branch master (28 Oct 2020)
Latest commit b1d8852 by Sam Harwell:
Merge pull request #48968 from sharwell/require-token
Update RegisterNotification to require a CancellationToken
Steps to Reproduce:
#nullable enable
using System.Diagnostics.CodeAnalysis;
class C<T> where T: new()
{
[NotNull, AllowNull] public T Prop { get => new T(); set { } }
public C(T t)
{
Prop = t;
Prop.ToString(); // ok
}
public void Init(T t)
{
Prop = t;
Prop.ToString(); // ok
}
public void Assignment(T t)
{
var c = new C<T>(t);
c.Prop = t;
c.Prop.ToString(); // ok
}
public void Initalizer(T t)
{
var c = new C<T>(t) { Prop = t };
c.Prop.ToString(); // CS8602
}
}
Expected Behavior:
No warnings. All examples assign values with the same nullability to the same property and dereference it
Actual Behavior:
False CS8602 Dereference of a possibly null reference. is reported for Initializer method only
I suspect the following method call might be missing when setting a nullable state for members used in object initializers
/// <summary>
/// When the allowed output of a property/indexer is not-null but the allowed input is maybe-null, we store a not-null value instead.
/// This way, assignment of a legal input value results in a legal output value.
/// This adjustment doesn't apply to oblivious properties/indexers.
/// </summary>
private void AdjustSetValue(BoundExpression left, TypeWithAnnotations declaredType, TypeWithAnnotations leftLValueType, ref TypeWithState rightState)
Version Used:
Steps to Reproduce:
Expected Behavior: No warnings. All examples assign values with the same nullability to the same property and dereference it
Actual Behavior: False
CS8602 Dereference of a possibly null reference.
is reported forInitializer
method onlyI suspect the following method call might be missing when setting a nullable state for members used in object initializers
/cc @jcouv