未验证 提交 37ce995a 编写于 作者: R Rikki Gibson 提交者: GitHub

Update operand flow state after an unboxing conversion (#38362)

上级 d9d57f18
......@@ -2453,11 +2453,6 @@ private void GetSlotsToMarkAsNotNullable(BoundExpression operand, ArrayBuilder<i
private static void MarkSlotsAsNotNull(ArrayBuilder<int> slots, ref LocalState stateToUpdate)
{
if (slots is null)
{
return;
}
foreach (int slot in slots)
{
stateToUpdate[slot] = NullableFlowState.NotNull;
......@@ -4858,9 +4853,14 @@ private static BoundConversion GetConversionIfApplicable(BoundExpression convers
break;
case ConversionKind.Unboxing:
if (operandType.MayBeNull && targetType.IsNonNullableValueType() && reportRemainingWarnings)
if (targetType.IsNonNullableValueType())
{
ReportDiagnostic(ErrorCode.WRN_UnboxPossibleNull, diagnosticLocationOpt);
if (operandType.MayBeNull && reportRemainingWarnings)
{
ReportDiagnostic(ErrorCode.WRN_UnboxPossibleNull, diagnosticLocationOpt);
}
LearnFromNonNullTest(conversionOperand, ref State);
}
else
{
......@@ -4979,11 +4979,7 @@ private static BoundConversion GetConversionIfApplicable(BoundExpression convers
// because the implied call to `.Value` will only succeed if not null.
if (conversionOperand != null)
{
int slot = MakeSlot(conversionOperand);
if (slot > 0)
{
this.State[slot] = NullableFlowState.NotNull;
}
LearnFromNonNullTest(conversionOperand, ref State);
}
}
goto case ConversionKind.ImplicitNullable;
......
......@@ -56034,6 +56034,175 @@ static void Main()
Diagnostic(ErrorCode.WRN_UnboxPossibleNull, "(T) v").WithLocation(13, 18));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_03()
{
var source =
@"public interface I { }
public struct S : I
{
static void M1(I? i)
{
S s = (S)i; // 1
_ = i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8605: Unboxing a possibly null value.
// S s = (S)i; // 1
Diagnostic(ErrorCode.WRN_UnboxPossibleNull, "(S)i").WithLocation(7, 15));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_04()
{
var source =
@"public interface I { }
public struct S : I
{
static void M1(I? i)
{
S s = (S)i!;
_ = i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics();
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_05()
{
var source =
@"public interface I { }
public class C
{
public I? i = new S();
}
public struct S : I
{
static void M1(C? c)
{
S s = (S)c?.i; // 1
_ = c.ToString();
_ = c.i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (12,15): warning CS8605: Unboxing a possibly null value.
// S s = (S)c?.i; // 1
Diagnostic(ErrorCode.WRN_UnboxPossibleNull, "(S)c?.i").WithLocation(12, 15));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_06()
{
var source =
@"public interface I { }
public class C
{
public I? i = new S();
}
public struct S : I
{
static void M1(C? c)
{
S? s = (S?)c?.i;
_ = c.ToString(); // 1
_ = c.i.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (13,13): warning CS8602: Dereference of a possibly null reference.
// _ = c.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(13, 13),
// (14,13): warning CS8602: Dereference of a possibly null reference.
// _ = c.i.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c.i").WithLocation(14, 13));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_07()
{
var source =
@"public interface I { }
public struct S : I
{
static void M1(I? i)
{
S s = (S)i; // 1
_ = i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8605: Unboxing a possibly null value.
// S s = (S)i; // 1
Diagnostic(ErrorCode.WRN_UnboxPossibleNull, "(S)i").WithLocation(7, 15));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_08()
{
var source =
@"public interface I { }
public class C
{
static void M1<T>(I? i)
{
T t = (T)i; // 1
_ = i.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8601: Possible null reference assignment.
// T t = (T)i; // 1
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "(T)i").WithLocation(7, 15),
// (8,13): warning CS8602: Dereference of a possibly null reference.
// _ = i.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "i").WithLocation(8, 13));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void UnboxingConversion_09()
{
var source =
@"public interface I { }
public class C
{
static void M1<T>(I? i) where T : struct
{
T t = (T)i; // 1
_ = i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8605: Unboxing a possibly null value.
// T t = (T)i; // 1
Diagnostic(ErrorCode.WRN_UnboxPossibleNull, "(T)i").WithLocation(7, 15));
}
[Fact]
public void DeconstructionConversion_NoDeconstructMethod()
{
......@@ -60308,6 +60477,55 @@ static void F4(int? x4)
Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "(long)x3").WithLocation(14, 19));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void Conversions_ExplicitNullable_06()
{
var source =
@"class C
{
int? i = null;
static void F1(C? c)
{
int i1 = (int)c?.i; // 1
_ = c.ToString();
_ = c.i.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,18): warning CS8629: Nullable value type may be null.
// int i1 = (int)c?.i; // 1
Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "(int)c?.i").WithLocation(7, 18));
}
[Fact]
[WorkItem(38170, "https://github.com/dotnet/roslyn/issues/38170")]
public void Conversions_ExplicitNullable_07()
{
var source =
@"class C
{
int? i = null;
static void F1(C? c)
{
int? i1 = (int?)c?.i;
_ = c.ToString(); // 1
_ = c.i.Value.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (8,13): warning CS8602: Dereference of a possibly null reference.
// _ = c.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(8, 13),
// (9,13): warning CS8629: Nullable value type may be null.
// _ = c.i.Value.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "c.i").WithLocation(9, 13));
}
[Fact]
[WorkItem(35334, "https://github.com/dotnet/roslyn/issues/35334")]
public void Conversions_ExplicitNullable_UserDefinedIntroducingNullability()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册