From b43d3e92da91f31b9e55c032d5bc8e9f9300e20d Mon Sep 17 00:00:00 2001 From: vsadov Date: Fri, 8 Mar 2019 15:51:00 -0800 Subject: [PATCH] more PR feedback --- .../Portable/FlowAnalysis/NullableWalker.cs | 15 +++--- .../Semantics/NullableReferenceTypesTests.cs | 50 +++++++++++++++++-- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index e369127577b..507d47d6b6b 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -1430,16 +1430,13 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre // a nullable value type created with its default constructor is by definition null resultState = NullableFlowState.MaybeNull; } - else + else if (constructor.ParameterCount == 1) { // if we deal with one-parameter ctor that takes underlying, then Value state is inferred from the argument. - if (constructor.ParameterCount == 1) + var parameterType = constructor.ParameterTypes[0]; + if (AreNullableAndUnderlyingTypes(type, parameterType.TypeSymbol, out TypeSymbolWithAnnotations underlyingType)) { - var parameterType = constructor.ParameterTypes[0]; - if (AreNullableAndUnderlyingTypes(type, parameterType.TypeSymbol, out TypeSymbolWithAnnotations underlyingType)) - { - TrackNullableStateWhenWrappingUnderlying(node, arguments[0], type, underlyingType); - } + TrackNullableStateOfNullableValue(node, arguments[0], type, underlyingType); } } } @@ -3671,11 +3668,11 @@ private void TrackNullableStateIfNullableConversion(BoundConversion node) if (AreNullableAndUnderlyingTypes(convertedType, operandType, out TypeSymbolWithAnnotations underlyingType)) { // Conversion of T to Nullable is equivalent to new Nullable(t). - TrackNullableStateWhenWrappingUnderlying(node, operand, convertedType, underlyingType); + TrackNullableStateOfNullableValue(node, operand, convertedType, underlyingType); } } - private void TrackNullableStateWhenWrappingUnderlying(BoundExpression node, BoundExpression operand, TypeSymbol convertedType, TypeSymbolWithAnnotations underlyingType) + private void TrackNullableStateOfNullableValue(BoundExpression node, BoundExpression operand, TypeSymbol convertedType, TypeSymbolWithAnnotations underlyingType) { int valueSlot = MakeSlot(operand); if (valueSlot > 0) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 79ba2052c08..6f4d6031ad7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -77944,7 +77944,53 @@ static void F() // (23,9): warning CS8602: Possible dereference of a null reference. // x.Value.F.ToString(); // warning Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x.Value.F").WithLocation(23, 9) -); + ); + } + + [WorkItem(32626, "https://github.com/dotnet/roslyn/issues/32626")] + [Fact] + public void NullableCtorErr() + { + var source = +@" +using System; + +struct S +{ + internal object? F; +} + +class Program +{ + static void F() + { + S? x = new S() { F = 2 }; + x.Value.F.ToString(); // ok baseline + + S? y = new Nullable(1); + y.Value.F.ToString(); // warning 1 + + S? z = new Nullable(null); + z.Value.F.ToString(); // warning 2 + } +} + +"; + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); + comp.VerifyDiagnostics( + // (16,32): error CS1503: Argument 1: cannot convert from 'int' to 'S' + // S? y = new Nullable(1); + Diagnostic(ErrorCode.ERR_BadArgType, "1").WithArguments("1", "int", "S").WithLocation(16, 32), + // (17,9): warning CS8602: Possible dereference of a null reference. + // y.Value.F.ToString(); // warning 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y.Value.F").WithLocation(17, 9), + // (19,32): error CS1503: Argument 1: cannot convert from '' to 'S' + // S? z = new Nullable(null); + Diagnostic(ErrorCode.ERR_BadArgType, "null").WithArguments("1", "", "S").WithLocation(19, 32), + // (20,9): warning CS8602: Possible dereference of a null reference. + // z.Value.F.ToString(); // warning 2 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "z.Value.F").WithLocation(20, 9) + ); } [WorkItem(32626, "https://github.com/dotnet/roslyn/issues/32626")] @@ -77990,8 +78036,6 @@ static void F() ); } - - [Fact] public void NullableT_AlwaysTrueOrFalse() { -- GitLab