From 9516be26a349892c78f2f89b1a2ffbf791bed3b7 Mon Sep 17 00:00:00 2001 From: vsadov Date: Wed, 13 Mar 2019 14:06:29 -0700 Subject: [PATCH] Report nullness warnings for nullable collections in foreach. Fixes:#31503 --- .../CSharp/Portable/FlowAnalysis/NullableWalker.cs | 8 ++++++++ .../Semantic/Semantics/NullableReferenceTypesTests.cs | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index 062b0ca75ed..5af8837bf91 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -2593,6 +2593,14 @@ private TypeWithState VisitCallReceiver(BoundCall node) { checkNullableValueType = true; } + else if (method.OriginalDefinition == compilation.GetSpecialTypeMember(SpecialMember.System_Nullable_T_get_Value)) + { + // call to get_Value may not occur directly in source, but may be inserted as a result of premature lowering. + // One example where we do it is foreach with nullables. + // The reason is Dev10 compatibility (see: UnwrapCollectionExpressionIfNullable in ForEachLoopBinder.cs) + // Regardless of the reasons, we know that the method does not tolerate nulls. + checkNullableValueType = true; + } // https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null // after arguments have been visited, and only if the receiver has not changed. diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index fd34dfd251d..8078c8728c7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -79781,8 +79781,15 @@ static void F1(S? s) } }"; var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); - // https://github.com/dotnet/roslyn/issues/31503: Report warning for `.Value.GetEnumerator()` calls. - comp.VerifyDiagnostics(); + + comp.VerifyDiagnostics( + // (11,27): warning CS8629: Nullable value type may be null. + // foreach (var i in s) // 1 + Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "s").WithLocation(11, 27), + // (18,27): warning CS8629: Nullable value type may be null. + // foreach (var i in t) // 2 + Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "t").WithLocation(18, 27) + ); } [Fact] -- GitLab