Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -6078,6 +6078,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
</data>
<data name="WRN_NullCheckingOnNullableValueType_Title" xml:space="preserve">
<value>Nullable value type is null-checked and will throw if null.</value>
</data>
<data name="ERR_ReAbstractionInNoPIAType" xml:space="preserve">
<value>Type '{0}' cannot be embedded because it has a re-abstraction of a member from base interface. Consider setting the 'Embed Interop Types' property to false.</value>
</data>
Expand Down
4 changes: 1 addition & 3 deletions src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ private void CompileMethod(
// Iterators handled in IteratorRewriter.cs
if (!methodSymbol.IsIterator)
{
var boundStatementsWithNullCheck = LocalRewriter.ConstructNullCheckedStatementList(methodSymbol.Parameters, boundStatements, factory);
var boundStatementsWithNullCheck = LocalRewriter.TryConstructNullCheckedStatementList(methodSymbol.Parameters, boundStatements, factory);

if (!boundStatementsWithNullCheck.IsDefault)
{
Expand All @@ -1249,8 +1249,6 @@ private void CompileMethod(
}
if (!(methodSymbol is SynthesizedStaticConstructor cctor) || cctor.ShouldEmit(processedInitializers.BoundInitializers))
{
CSharpSyntaxNode syntax = methodSymbol.GetNonNullSyntaxNode();

var boundBody = BoundStatementList.Synthesized(syntax, boundStatements);

var emittedBody = GenerateMethodBody(
Expand Down
14 changes: 8 additions & 6 deletions src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1738,12 +1738,6 @@ internal enum ErrorCode

ERR_ReAbstractionInNoPIAType = 8750,

ERR_NeedSpaceBetweenExclamationAndEquals = 8716,
ERR_MustNullCheckInImplementation = 8717,
ERR_NonNullableValueTypeIsNullChecked = 8718,
WRN_NullCheckedHasDefaultNull = 8719,
ERR_NullCheckingOnByRefParameter = 8720,
WRN_NullCheckingOnNullableValueType = 8721,
#endregion diagnostics introduced for C# 8.0

#region diagnostics introduced in C# 9.0
Expand Down Expand Up @@ -1874,7 +1868,15 @@ internal enum ErrorCode
ERR_CopyConstructorWrongAccessibility = 8878,
ERR_NonPrivateAPIInRecord = 8879,

ERR_NeedSpaceBetweenExclamationAndEquals = 8890,
ERR_MustNullCheckInImplementation = 8891,
ERR_NonNullableValueTypeIsNullChecked = 8892,
WRN_NullCheckedHasDefaultNull = 8893,
ERR_NullCheckingOnByRefParameter = 8894,
WRN_NullCheckingOnNullableValueType = 8895,

#endregion diagnostics introduced for C# 9.0

// Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd)
}
}
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/Portable/Errors/MessageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ internal enum MessageID
IDS_OverrideWithConstraints = MessageBase + 12761,
IDS_FeatureNestedStackalloc = MessageBase + 12762,
IDS_FeatureSwitchExpression = MessageBase + 12763,
IDS_ParameterNullChecking = MessageBase + 12764,
IDS_FeatureAsyncUsing = MessageBase + 12764,
IDS_FeatureLambdaDiscardParameters = MessageBase + 12765,
IDS_FeatureLocalFunctionAttributes = MessageBase + 12766,
Expand All @@ -211,6 +210,8 @@ internal enum MessageID
IDS_FeatureNullPointerConstantPattern = MessageBase + 12783,
IDS_FeatureModuleInitializers = MessageBase + 12784,
IDS_FeatureTargetTypedConditional = MessageBase + 12785,

IDS_ParameterNullChecking = MessageBase + 12786,
}

// Message IDs may refer to strings that need to be localized.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ public override BoundNode VisitLambda(BoundLambda node)
try
{
_factory.CurrentFunction = node.Symbol;
var visited = (BoundLambda)base.VisitLambda(node);
var visited = (BoundLambda)base.VisitLambda(node)!;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a Debug.Assert(visited is object); instead of a suppression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the suppression with a Debug.Assert. An additional warning, but it should be fine. 👍

Copy link
Contributor Author

@kevinsun-dev kevinsun-dev Jul 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought it was a warning, turns out it was an error:
LocalRewriter.cs(257,31): error CS8600: Converting null literal or possible null value to non-nullable type.
Reverted it back to what it was for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a warning locally but we push all warnings to errors in the CI runs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning is because you need to cast it to BoundLambda?, not BoundLambda.


if (RewriteNullChecking(visited.Body) is BoundBlock newBody)
{
visited = visited.Update(visited.UnboundLambda, visited.Symbol, newBody, visited.Diagnostics, visited.Binder, visited.Type);
Expand Down Expand Up @@ -314,7 +315,8 @@ static bool hasReturnTypeOrParameter(LocalFunctionSymbol localFunction, Func<Typ
_instrumenter = RemoveDynamicAnalysisInjectors(oldInstrumenter);
}

var visited = (BoundLocalFunctionStatement)base.VisitLocalFunctionStatement(node);
var visited = (BoundLocalFunctionStatement)base.VisitLocalFunctionStatement(node)!;

if (!localFunction.IsIterator && RewriteNullChecking(visited.Body) is BoundBlock newBody)
{
visited = visited.Update(localFunction, newBody, null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
Expand All @@ -10,15 +13,20 @@ internal sealed partial class LocalRewriter
{
private BoundBlock RewriteNullChecking(BoundBlock block)
{
var statementList = ConstructNullCheckedStatementList(_factory.CurrentFunction.Parameters, block.Statements, _factory);
if (block is null)
{
return null;
}

var statementList = TryConstructNullCheckedStatementList(_factory.CurrentFunction.Parameters, block.Statements, _factory);
if (statementList.IsDefault)
{
return null;
}
return _factory.Block(block.Locals, statementList);
}

internal static ImmutableArray<BoundStatement> ConstructNullCheckedStatementList(ImmutableArray<ParameterSymbol> parameters,
internal static ImmutableArray<BoundStatement> TryConstructNullCheckedStatementList(ImmutableArray<ParameterSymbol> parameters,
ImmutableArray<BoundStatement> existingStatements,
SyntheticBoundNodeFactory factory)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,9 @@ protected BoundStatement GenerateParameterStorage(LocalSymbol stateMachineVariab
}
}

bodyBuilder.Add(GenerateStateMachineCreation(stateMachineVariable, frameType));
var builtBody = bodyBuilder.ToImmutableAndFree();
ImmutableArray<BoundStatement> newBody = LocalRewriter.ConstructNullCheckedStatementList(method.Parameters, builtBody, F);
return F.Block(
ImmutableArray.Create(stateMachineVariable),
newBody.IsDefault ? builtBody : newBody);
ImmutableArray<BoundStatement> newBody = LocalRewriter.TryConstructNullCheckedStatementList(method.Parameters, builtBody, F);
return newBody.IsDefault ? F.Block(builtBody) : F.Block(ImmutableArray.Create(stateMachineVariable), newBody);
}

protected SynthesizedImplementationMethod OpenMethodImplementation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ internal ImmutableArray<BoundExpression> MakeTempsForDiscardArguments(ImmutableA
return arguments;
}

#nullable disable
internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrittenExpr, BinaryOperatorKind operatorKind)
{
Debug.Assert((operatorKind == BinaryOperatorKind.Equal) || (operatorKind == BinaryOperatorKind.NotEqual) ||
Expand Down Expand Up @@ -1531,7 +1532,7 @@ internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrit
}
if (operatorKind == BinaryOperatorKind.NullableNullEqual || operatorKind == BinaryOperatorKind.NullableNullNotEqual)
{
return RewriteNullableNullEquality(syntax, operatorKind, rewrittenExpr, Literal(ConstantValue.Null, objectType), boolType);
return RewriteNullableNullEquality(syntax, operatorKind, rewrittenExpr, Literal(ConstantValue.Null, objectType), boolType);
}
else
{
Expand Down Expand Up @@ -1615,5 +1616,7 @@ internal BoundExpression RewriteNullableNullEquality(

return result;
}
// PROTOTYPE(BangBang): Re-enable annotations
#nullable enable
}
}
40 changes: 18 additions & 22 deletions src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6923,7 +6923,7 @@ private FunctionPointerTypeSyntax ParseFunctionPointerTypeSyntax()
var lessThanTokenError = WithAdditionalDiagnostics(SyntaxFactory.MissingToken(SyntaxKind.LessThanToken), GetExpectedTokenError(SyntaxKind.LessThanToken, SyntaxKind.None));
var missingTypes = _pool.AllocateSeparated<ParameterSyntax>();
var missingTypeName = CreateMissingIdentifierName();
var missingType = SyntaxFactory.Parameter(attributeLists: default, modifiers: default, missingTypeName, identifier: CreateMissingIdentifierToken(), @default: null);
var missingType = SyntaxFactory.Parameter(attributeLists: default, modifiers: default, missingTypeName, identifier: CreateMissingIdentifierToken(), exclamationToken: null, @default: null);
missingTypes.Add(missingType);
// Handle the simple case of delegate*>. We don't try to deal with any variation of delegate*invalid>, as
// we don't know for sure that the expression isn't a relational with something else.
Expand All @@ -6949,7 +6949,7 @@ private FunctionPointerTypeSyntax ParseFunctionPointerTypeSyntax()
ParseParameterModifiers(modifiers, isFunctionPointerParameter: true);

var parameterType = ParseTypeOrVoid();
types.Add(SyntaxFactory.Parameter(attributeLists: default, modifiers, parameterType, identifier: CreateMissingIdentifierToken(), @default: null));
types.Add(SyntaxFactory.Parameter(attributeLists: default, modifiers, parameterType, identifier: CreateMissingIdentifierToken(), exclamationToken: null, @default: null));

if (skipBadFunctionPointerParameterListTokens() == PostSkipAction.Abort)
{
Expand Down Expand Up @@ -10413,26 +10413,6 @@ private bool IsPossibleAnonymousMethodExpression()
tokenIndex++;
}

if (precedence <= Precedence.Lambda)
{
SyntaxKind token1 = this.PeekToken(1).Kind;
if (token1 == SyntaxKind.EqualsGreaterThanToken)
{
return true;
}

if (token1 == SyntaxKind.ExclamationToken && this.PeekToken(2).Kind == SyntaxKind.EqualsGreaterThanToken)
{
return true;
}

// Broken case but error will be added in lambda function.
if (token1 == SyntaxKind.ExclamationEqualsToken && this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken)
{
return true;
}
}

return this.PeekToken(tokenIndex).Kind == SyntaxKind.DelegateKeyword;
}

Expand Down Expand Up @@ -11261,6 +11241,22 @@ private bool IsPossibleLambdaExpression(Precedence precedence)
return false;
}

SyntaxKind token1 = this.PeekToken(1).Kind;
if (token1 == SyntaxKind.EqualsGreaterThanToken)
{
return true;
}
if (token1 == SyntaxKind.ExclamationToken && this.PeekToken(2).Kind == SyntaxKind.EqualsGreaterThanToken)
{
return true;
}

// Broken case but error will be added in lambda function.
if (token1 == SyntaxKind.ExclamationEqualsToken && this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken)
{
return true;
}

// If we start with `static` or `async static` then just jump past those and do the
// analysis after that point. Note, we don't just blindly consume `async` in `static
// async` because that `async` may not be a modifier (it may just be an identifier) and
Expand Down
4 changes: 4 additions & 0 deletions src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.AddModifier
Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.Update(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken delegateKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax block, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.ExclamationToken.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax> attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.WithExclamationToken(Microsoft.CodeAnalysis.SyntaxToken exclamationToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.DefaultKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken defaultKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.WithDefaultKeyword(Microsoft.CodeAnalysis.SyntaxToken defaultKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
Expand All @@ -16,6 +19,7 @@ Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedLambdaExpressionSyntax.WithMod
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.AddModifiers(params Microsoft.CodeAnalysis.SyntaxToken[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.Update(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax parameter, Microsoft.CodeAnalysis.SyntaxToken arrowToken, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax block, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Parameter(Microsoft.CodeAnalysis.SyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax> attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
Microsoft.CodeAnalysis.CSharp.SyntaxKind.DefaultConstraint = 9057 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
abstract Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousFunctionExpressionSyntax.Modifiers.get -> Microsoft.CodeAnalysis.SyntaxTokenList
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDefaultConstraint(Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ internal int MethodHashCode()
public override bool IsDiscard => false;
public override bool IsParams => false;
public override bool IsImplicitlyDeclared => true;
public override bool IsNullChecked => false;
internal override MarshalPseudoCustomAttributeData? MarshallingInformation => null;
internal override bool IsMetadataOptional => false;
internal override bool IsMetadataIn => RefKind == RefKind.In;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ IParameterSymbol IParameterSymbol.OriginalDefinition

bool IParameterSymbol.IsParams => _underlying.IsParams;

bool IParameterSymbol.IsNullChecked => _underlying.IsNullChecked;

bool IParameterSymbol.IsOptional => _underlying.IsOptional;

bool IParameterSymbol.IsThis => _underlying.IsThis;
Expand Down
Loading