未验证 提交 53b2957f 编写于 作者: R Rikki Gibson 提交者: GitHub

Update argument state when parameter has not-null type (#46072)

上级 e128267a
......@@ -4955,7 +4955,7 @@ static bool hasNoNonNullableCounterpart(TypeSymbol type)
case RefKind.In:
{
// learn from post-conditions [Maybe/NotNull, Maybe/NotNullWhen] without using an assignment
learnFromPostConditions(argument, parameterAnnotations);
learnFromPostConditions(argument, parameterType, parameterAnnotations);
}
break;
case RefKind.Ref:
......@@ -5139,11 +5139,15 @@ static TypeWithState applyPostConditionsWhenFalse(TypeWithState typeWithState, F
return typeWithState;
}
void learnFromPostConditions(BoundExpression argument, FlowAnalysisAnnotations parameterAnnotations)
void learnFromPostConditions(BoundExpression argument, TypeWithAnnotations parameterType, FlowAnalysisAnnotations parameterAnnotations)
{
// Note: NotNull = NotNullWhen(true) + NotNullWhen(false)
bool notNullWhenTrue = (parameterAnnotations & FlowAnalysisAnnotations.NotNullWhenTrue) != 0;
bool notNullWhenFalse = (parameterAnnotations & FlowAnalysisAnnotations.NotNullWhenFalse) != 0;
bool disallowNull = (parameterAnnotations & FlowAnalysisAnnotations.DisallowNull) != 0;
bool setNotNullFromParameterType = !argument.IsSuppressed
&& !parameterType.Type.IsPossiblyNullableReferenceTypeTypeParameter()
&& parameterType.NullableAnnotation.IsNotAnnotated();
// Note: MaybeNull = MaybeNullWhen(true) + MaybeNullWhen(false)
bool maybeNullWhenTrue = (parameterAnnotations & FlowAnalysisAnnotations.MaybeNullWhenTrue) != 0;
......@@ -5153,7 +5157,9 @@ void learnFromPostConditions(BoundExpression argument, FlowAnalysisAnnotations p
{
LearnFromNullTest(argument, ref State);
}
else if (notNullWhenTrue && notNullWhenFalse && !IsConditionalState && !(maybeNullWhenTrue && maybeNullWhenFalse))
else if (((notNullWhenTrue && notNullWhenFalse) || disallowNull || setNotNullFromParameterType)
&& !IsConditionalState
&& !(maybeNullWhenTrue || maybeNullWhenFalse))
{
LearnFromNonNullTest(argument, ref State);
}
......
......@@ -3001,19 +3001,19 @@ class C<T, U>
{
public T this[U u] { get => throw null!; set => throw null!; }
public static void M(object? o1, object o2)
public static void M(bool b, object? o1, object o2)
{
var c1 = CExt.Create(o1, o2);
c1[o1] = o2;
_ = c1[o1];
if (b) c1[o1] = o2;
if (b) _ = c1[o1];
var c2 = CExt.Create(o2, o1);
c2[o2] = o1;
_ = c2[o2];
if (b) c2[o2] = o1;
if (b) _ = c2[o2];
var c3 = CExt.Create(o1 ?? o2, o2);
c3[o1] = o2;
_ = c3[o1];
if (b) c3[o1] = o2;
if (b) _ = c3[o1];
}
}
static class CExt
......@@ -3023,21 +3023,21 @@ static class CExt
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (9,12): warning CS8604: Possible null reference argument for parameter 'u' in 'object? C<object?, object>.this[object u]'.
// c1[o1] = o2;
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object? C<object?, object>.this[object u]").WithLocation(9, 12),
// (10,16): warning CS8604: Possible null reference argument for parameter 'u' in 'object? C<object?, object>.this[object u]'.
// _ = c1[o1];
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object? C<object?, object>.this[object u]").WithLocation(10, 16),
// (13,18): warning CS8601: Possible null reference assignment.
// c2[o2] = o1;
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "o1").WithLocation(13, 18),
// (17,12): warning CS8604: Possible null reference argument for parameter 'u' in 'object C<object, object>.this[object u]'.
// c3[o1] = o2;
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object C<object, object>.this[object u]").WithLocation(17, 12),
// (18,16): warning CS8604: Possible null reference argument for parameter 'u' in 'object C<object, object>.this[object u]'.
// _ = c3[o1];
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object C<object, object>.this[object u]").WithLocation(18, 16));
// (9,19): warning CS8604: Possible null reference argument for parameter 'u' in 'object? C<object?, object>.this[object u]'.
// if (b) c1[o1] = o2;
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object? C<object?, object>.this[object u]").WithLocation(9, 19),
// (10,23): warning CS8604: Possible null reference argument for parameter 'u' in 'object? C<object?, object>.this[object u]'.
// if (b) _ = c1[o1];
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object? C<object?, object>.this[object u]").WithLocation(10, 23),
// (13,25): warning CS8601: Possible null reference assignment.
// if (b) c2[o2] = o1;
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "o1").WithLocation(13, 25),
// (17,19): warning CS8604: Possible null reference argument for parameter 'u' in 'object C<object, object>.this[object u]'.
// if (b) c3[o1] = o2;
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object C<object, object>.this[object u]").WithLocation(17, 19),
// (18,23): warning CS8604: Possible null reference argument for parameter 'u' in 'object C<object, object>.this[object u]'.
// if (b) _ = c3[o1];
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "o1").WithArguments("u", "object C<object, object>.this[object u]").WithLocation(18, 23));
var syntaxTree = comp.SyntaxTrees[0];
var root = syntaxTree.GetRoot();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册