diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index d5e3d1fea6c775ba88a99147eadc5c36236799d8..75ccdb370dd9000c3f3483bd263c2648699ea4c1 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -4487,11 +4487,6 @@ private bool IsUsingAliasInScope(string name) return BadExpression(node, boundLeft); } - if (boundLeft.Kind == BoundKind.DefaultOperator && boundLeft.ConstantValue == ConstantValue.Null) - { - Error(diagnostics, ErrorCode.WRN_DotOnDefault, node, leftType); - } - var lookupResult = LookupResult.GetInstance(); try { @@ -4649,6 +4644,14 @@ private bool IsUsingAliasInScope(string name) } } + private static void WarnOnAccessOfOffDefault(CSharpSyntaxNode node, BoundExpression boundLeft, DiagnosticBag diagnostics) + { + if (boundLeft != null && boundLeft.Kind == BoundKind.DefaultOperator && boundLeft.ConstantValue == ConstantValue.Null) + { + Error(diagnostics, ErrorCode.WRN_DotOnDefault, node, boundLeft.Type); + } + } + /// /// Create a value from the expression that can be used as a left-hand-side /// of a member access. This method special-cases method and property @@ -5256,6 +5259,11 @@ private static void CombineExtensionMethodArguments(BoundExpression receiver, An } } + if (!fieldSymbol.IsStatic) + { + WarnOnAccessOfOffDefault(node, receiver, diagnostics); + } + TypeSymbol fieldType = fieldSymbol.GetFieldType(this.FieldsBeingBound); BoundExpression expr = new BoundFieldAccess(node, receiver, fieldSymbol, constantValueOpt, resultKind, fieldType, hasErrors: (hasErrors || hasError)); @@ -5320,6 +5328,11 @@ private bool InEnumMemberInitializer() { bool hasError = this.CheckInstanceOrStatic(node, receiver, propertySymbol, ref lookupResult, diagnostics); + if (!propertySymbol.IsStatic) + { + WarnOnAccessOfOffDefault(node, receiver, diagnostics); + } + return new BoundPropertyAccess(node, receiver, propertySymbol, lookupResult, propertySymbol.Type, hasErrors: (hasErrors || hasError)); } @@ -5337,6 +5350,11 @@ private bool InEnumMemberInitializer() bool hasError = this.CheckInstanceOrStatic(node, receiver, eventSymbol, ref lookupResult, diagnostics); + if (!eventSymbol.IsStatic) + { + WarnOnAccessOfOffDefault(node, receiver, diagnostics); + } + return new BoundEventAccess(node, receiver, eventSymbol, isUsableAsField, lookupResult, eventSymbol.Type, hasErrors: (hasErrors || hasError)); } @@ -5562,10 +5580,8 @@ private BoundExpression BindElementOrIndexerAccess(ExpressionSyntax node, BoundE { return BadIndexerExpression(node, expr, analyzedArguments, null, diagnostics); } - else if (expr.Kind == BoundKind.DefaultOperator && ((BoundDefaultOperator)expr).ConstantValue == ConstantValue.Null) - { - Error(diagnostics, ErrorCode.WRN_DotOnDefault, node, expr.Type); - } + + WarnOnAccessOfOffDefault(node, expr, diagnostics); // Did we have any errors? if (analyzedArguments.HasErrors || expr.HasAnyErrors) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index e02c0317ff64a36c2e75f164b08fb3f58e8f42c0..c2a0ad6be484cad159c90d3acacc91c161282525 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -849,6 +849,15 @@ private static void CheckRestrictedTypeReceiver(BoundExpression expression, Comp gotError = true; } + if (!method.IsStatic) + { + WarnOnAccessOfOffDefault(node.Kind() == SyntaxKind.InvocationExpression ? + ((InvocationExpressionSyntax)node).Expression : + node, + receiver, + diagnostics); + } + return new BoundCall(node, receiver, method, args, argNames, argRefKinds, isDelegateCall: false, expanded: expanded, invokedAsExtensionMethod: invokedAsExtensionMethod, argsToParamsOpt: argsToParams, resultKind: LookupResultKind.Viable, type: returnType, hasErrors: gotError); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index 1bc21bab491ab4208e75e2df43d891d05e968709..1d079fb17745ea86727c7593f08fdaad6b2966cf 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -20816,13 +20816,7 @@ static class C // (26,9): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'T6' is null Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T6).GetHashCode").WithArguments("T6").WithLocation(26, 9), // (28,9): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'T6' is null - Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T6).P").WithArguments("T6").WithLocation(28, 9), - // (31,9): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'object' is null - Diagnostic(ErrorCode.WRN_DotOnDefault, "default(object).E").WithArguments("object").WithLocation(31, 9), - // (35,9): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'T4' is null - Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T4).E").WithArguments("T4").WithLocation(35, 9), - // (37,9): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'T6' is null - Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T6).E").WithArguments("T6").WithLocation(37, 9)); + Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T6).P").WithArguments("T6").WithLocation(28, 9)); } [Fact] @@ -20894,6 +20888,31 @@ class C Diagnostic(ErrorCode.WRN_DotOnDefault, "default(T4)[1]").WithArguments("T4").WithLocation(38, 9)); } + [Fact] + public void CS1720WRN_DotOnDefault03() + { + var source = +@"static class A +{ + static void Main() + { + System.Console.WriteLine(default(string).IsNull()); + } + + internal static bool IsNull(this string val) + { + return (object)val == null; + } +} +"; + CompileAndVerify(source, expectedOutput: "True", additionalRefs: new[] { SystemCoreRef }).VerifyDiagnostics( + // Do not report the following warning: + // (5,34): warning CS1720: Expression will always cause a System.NullReferenceException because the default value of 'string' is null + // System.Console.WriteLine(default(string).IsNull()); + // Diagnostic(ErrorCode.WRN_DotOnDefault, "default(string).IsNull").WithArguments("string").WithLocation(5, 34) + ); + } + [Fact] public void CS1723WRN_BadXMLRefTypeVar() {