Skip to content

Commit

Permalink
Merge pull request #19658 from OmarTawfik/isconst-modreqs
Browse files Browse the repository at this point in the history
Adding IsConst modreq on ref readonly signatures
  • Loading branch information
VSadov authored Jun 23, 2017
2 parents 2d926b1 + 743a3bc commit 55d359d
Show file tree
Hide file tree
Showing 28 changed files with 5,569 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1017,9 +1017,14 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()

private DiagnosticInfo InitializeUseSiteDiagnostic(DiagnosticInfo diagnostic)
{
Debug.Assert(!CSDiagnosticInfo.IsEmpty(diagnostic));
if (_packedFlags.IsUseSiteDiagnosticPopulated)
{
return _uncommonFields?._lazyUseSiteDiagnostic;
}

if (diagnostic != null)
{
Debug.Assert(!CSDiagnosticInfo.IsEmpty(diagnostic));
diagnostic = InterlockedOperations.Initialize(ref AccessUncommonFields()._lazyUseSiteDiagnostic, diagnostic, CSDiagnosticInfo.EmptyErrorInfo);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;

Expand Down Expand Up @@ -302,6 +304,12 @@ public PEParameterSymbolWithCustomModifiers(
_customModifiers = CSharpCustomModifier.Convert(customModifiers);
_refCustomModifiers = CSharpCustomModifier.Convert(refCustomModifiers);

if (this.RefKind != RefKind.RefReadOnly && _refCustomModifiers.Any(modifier => !modifier.IsOptional && modifier.Modifier.IsWellKnownTypeIsConst()))
{
// IsConst modreq is only accepted on RefReadOnly symbols
isBad = true;
}

Debug.Assert(_refCustomModifiers.IsEmpty || isByRef);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Reflection.Metadata;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.DocumentationComments;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.PooledObjects;

namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
{
Expand Down Expand Up @@ -69,6 +69,7 @@ internal static PEPropertySymbol Create(
var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx);
Debug.Assert(propertyParams.Length > 0);

var isBad = false;
var returnInfo = propertyParams[0];
PEPropertySymbol result;

Expand All @@ -78,10 +79,10 @@ internal static PEPropertySymbol Create(
}
else
{
result = new PEPropertySymbolWithCustomModifiers(moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams, metadataDecoder);
result = new PEPropertySymbolWithCustomModifiers(moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams, metadataDecoder, out isBad);
}

if (propEx != null)
if (propEx != null || isBad)
{
result._lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, result);
}
Expand Down Expand Up @@ -731,14 +732,18 @@ public PEPropertySymbolWithCustomModifiers(
PEMethodSymbol getMethod,
PEMethodSymbol setMethod,
ParamInfo<TypeSymbol>[] propertyParams,
MetadataDecoder metadataDecoder)
MetadataDecoder metadataDecoder,
out bool isBad)
: base (moduleSymbol, containingType, handle, getMethod, setMethod,
propertyParams[0].CustomModifiers.NullToEmpty().Length + propertyParams[0].RefCustomModifiers.NullToEmpty().Length,
propertyParams, metadataDecoder)
{
var returnInfo = propertyParams[0];
_typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers);
_refCustomModifiers = CSharpCustomModifier.Convert(returnInfo.RefCustomModifiers);

// IsConst modreq is only accepted on RefReadOnly symbols
isBad = this.RefKind != RefKind.RefReadOnly && _refCustomModifiers.Any(modifier => !modifier.IsOptional && modifier.Modifier.IsWellKnownTypeIsConst());
}

public override ImmutableArray<CustomModifier> TypeCustomModifiers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ internal override Cci.PrimitiveTypeCode GetPrimitiveTypeCode(PEModuleSymbol modu
return type.PrimitiveTypeCode;
}

internal override bool IsVolatileModifierType(PEModuleSymbol moduleSymbol, TypeSymbol type)
internal override bool IsAcceptedVolatileModifierType(PEModuleSymbol moduleSymbol, TypeSymbol type)
{
return type.SpecialType == SpecialType.System_Runtime_CompilerServices_IsVolatile;
}

internal override bool IsAcceptedIsConstModifierType(TypeSymbol type)
{
return type.IsWellKnownTypeIsConst();
}

internal override TypeSymbol GetSZArrayTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol elementType, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers)
{
if (elementType is UnsupportedMetadataTypeSymbol)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static bool HasRefOrOutParameter(this PropertySymbol property)
{
foreach (ParameterSymbol param in property.Parameters)
{
if (param.RefKind != RefKind.None)
if (param.RefKind == RefKind.Ref || param.RefKind == RefKind.Out)
{
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ internal static void CopyMethodCustomModifiers(
// have already been compared.
MethodSymbol constructedSourceMethod = sourceMethod.ConstructIfGeneric(destinationMethod.TypeArguments);

customModifiers = CustomModifiersTuple.Create(constructedSourceMethod.ReturnTypeCustomModifiers,
destinationMethod.ReturnsByRef ? constructedSourceMethod.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty);
customModifiers = CustomModifiersTuple.Create(
constructedSourceMethod.ReturnTypeCustomModifiers,
destinationMethod.RefKind != RefKind.None ? constructedSourceMethod.RefCustomModifiers : ImmutableArray<CustomModifier>.Empty);

parameters = CopyParameterCustomModifiers(constructedSourceMethod.Parameters, destinationMethod.Parameters, alsoCopyParamsModifier);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ private void ComputeParameters()
arglistToken: out arglistToken,
allowRefOrOut: true,
allowThis: true,
addIsConstModifier: false,
diagnostics: diagnostics);

ParameterHelpers.EnsureIsReadOnlyAttributeExists(parameters, diagnostics, modifyCompilationForRefReadOnly: false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public static ImmutableArray<ParameterSymbol> MakeParameters(
out SyntaxToken arglistToken,
DiagnosticBag diagnostics,
bool allowRefOrOut,
bool allowThis)
bool allowThis,
bool addIsConstModifier)
{
arglistToken = default(SyntaxToken);

Expand Down Expand Up @@ -91,6 +92,7 @@ public static ImmutableArray<ParameterSymbol> MakeParameters(
parameterIndex,
(paramsKeyword.Kind() != SyntaxKind.None),
parameterIndex == 0 && thisKeyword.Kind() != SyntaxKind.None,
addIsConstModifier,
diagnostics);

ReportParameterErrors(owner, parameterSyntax, parameter, thisKeyword, paramsKeyword, firstDefault, diagnostics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ protected override void MethodChecks(DiagnosticBag diagnostics)
bodyBinder, this, parameterList, out arglistToken,
allowRefOrOut: true,
allowThis: false,
addIsConstModifier: false,
diagnostics: diagnostics);

_lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ internal override LexicalSortKey GetLexicalSortKey()

private sealed class InvokeMethod : SourceDelegateMethodSymbol
{
private readonly RefKind refKind;
private readonly RefKind _refKind;
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;

internal InvokeMethod(
SourceMemberContainerTypeSymbol delegateType,
Expand All @@ -243,13 +244,14 @@ internal InvokeMethod(
DiagnosticBag diagnostics)
: base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, DeclarationModifiers.Virtual | DeclarationModifiers.Public)
{
this.refKind = refKind;
this._refKind = refKind;

SyntaxToken arglistToken;
var parameters = ParameterHelpers.MakeParameters(
binder, this, syntax.ParameterList, out arglistToken,
allowRefOrOut: true,
allowThis: false,
addIsConstModifier: true,
diagnostics: diagnostics);

if (arglistToken.Kind() == SyntaxKind.ArgListKeyword)
Expand All @@ -260,6 +262,16 @@ internal InvokeMethod(
diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken));
}

if (_refKind == RefKind.RefReadOnly)
{
var isConstType = binder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.ReturnType);
_refCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType));
}
else
{
_refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
}

InitializeParameters(parameters);
}

Expand All @@ -270,7 +282,7 @@ public override string Name

internal override RefKind RefKind
{
get { return refKind; }
get { return _refKind; }
}

internal override LexicalSortKey GetLexicalSortKey()
Expand All @@ -288,14 +300,16 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions,
{
base.AfterAddingTypeMembersChecks(conversions, diagnostics);

if (refKind == RefKind.RefReadOnly)
if (_refKind == RefKind.RefReadOnly)
{
var syntax = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, syntax.ReturnType.GetLocation(), modifyCompilationForRefReadOnly: true);
}

ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
}

public override ImmutableArray<CustomModifier> RefCustomModifiers => _refCustomModifiers;
}

private sealed class BeginInvokeMethod : SourceDelegateMethodSymbol
Expand Down Expand Up @@ -343,15 +357,15 @@ internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetReturnTypeAttrib

private sealed class EndInvokeMethod : SourceDelegateMethodSymbol
{
private readonly RefKind refKind;
private readonly InvokeMethod _invoke;

internal EndInvokeMethod(
InvokeMethod invoke,
TypeSymbol iAsyncResultType,
DelegateDeclarationSyntax syntax)
: base((SourceNamedTypeSymbol)invoke.ContainingType, invoke.ReturnType, syntax, MethodKind.Ordinary, DeclarationModifiers.Virtual | DeclarationModifiers.Public)
{
this.refKind = invoke.RefKind;
_invoke = invoke;

var parameters = ArrayBuilder<ParameterSymbol>.GetInstance();
int ordinal = 0;
Expand All @@ -369,24 +383,13 @@ internal EndInvokeMethod(
InitializeParameters(parameters.ToImmutableAndFree());
}

protected override SourceMethodSymbol BoundAttributesSource
{
get
{
// copy return attributes from InvokeMethod
return (SourceMethodSymbol)((SourceNamedTypeSymbol)this.ContainingSymbol).DelegateInvokeMethod;
}
}
protected override SourceMethodSymbol BoundAttributesSource => _invoke;

public override string Name
{
get { return WellKnownMemberNames.DelegateEndInvokeName; }
}
public override string Name => WellKnownMemberNames.DelegateEndInvokeName;

internal override RefKind RefKind
{
get { return refKind; }
}
internal override RefKind RefKind => _invoke.RefKind;

public override ImmutableArray<CustomModifier> RefCustomModifiers => _invoke.RefCustomModifiers;
}

private static string GetUniqueParameterName(ArrayBuilder<ParameterSymbol> currentParameters, string name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
signatureBinder, this, syntax.ParameterList, out arglistToken,
allowRefOrOut: true,
allowThis: true,
addIsConstModifier: IsVirtual || IsAbstract,
diagnostics: diagnostics);

_lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
Expand Down Expand Up @@ -330,11 +331,19 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB

if ((object)overriddenMethod != null)
{
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyCustomModifiers,
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: true);
}
}
else if (_refKind == RefKind.RefReadOnly)
{
var isConstType = withTypeParamsBinder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.ReturnType);

_lazyCustomModifiers = CustomModifiersTuple.Create(
typeCustomModifiers: ImmutableArray<CustomModifier>.Empty,
refCustomModifiers: ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType)));
}
}
else if ((object)_explicitInterfaceType != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static SourceParameterSymbol Create(
int ordinal,
bool isParams,
bool isExtensionMethodThis,
bool addIsConstModifier,
DiagnosticBag declarationDiagnostics)
{
var name = identifier.ValueText;
Expand All @@ -49,6 +50,25 @@ public static SourceParameterSymbol Create(
identifier.Parent.GetLocation());
}

if (addIsConstModifier && refKind == RefKind.RefReadOnly)
{
var isConstType = context.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, declarationDiagnostics, syntax);

return new SourceComplexParameterSymbolWithCustomModifiers(
owner,
ordinal,
parameterType,
refKind,
ImmutableArray<CustomModifier>.Empty,
ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType)),
name,
locations,
syntax.GetReference(),
ConstantValue.Unset,
isParams,
isExtensionMethodThis);
}

if (!isParams &&
!isExtensionMethodThis &&
(syntax.Default == null) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ private SourcePropertySymbol(
_lazyParameters = CustomModifierUtils.CopyParameterCustomModifiers(overriddenOrImplementedProperty.Parameters, _lazyParameters, alsoCopyParamsModifier: isOverride);
}
}
else if (_refKind == RefKind.RefReadOnly)
{
var isConstType = bodyBinder.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst, diagnostics, syntax.Type);

_customModifiers = CustomModifiersTuple.Create(
ImmutableArray<CustomModifier>.Empty,
ImmutableArray.Create(CSharpCustomModifier.CreateRequired(isConstType)));
}

if (!hasAccessorList)
{
Expand Down Expand Up @@ -781,7 +789,7 @@ private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, bool isExp
}

private static ImmutableArray<ParameterSymbol> MakeParameters(
Binder binder, SourcePropertySymbol owner, BaseParameterListSyntax parameterSyntaxOpt, DiagnosticBag diagnostics)
Binder binder, SourcePropertySymbol owner, BaseParameterListSyntax parameterSyntaxOpt, DiagnosticBag diagnostics, bool addIsConstModifier)
{
if (parameterSyntaxOpt == null)
{
Expand All @@ -798,6 +806,7 @@ private static ImmutableArray<ParameterSymbol> MakeParameters(
binder, owner, parameterSyntaxOpt, out arglistToken,
allowRefOrOut: false,
allowThis: false,
addIsConstModifier: addIsConstModifier,
diagnostics: diagnostics);

if (arglistToken.Kind() != SyntaxKind.None)
Expand Down Expand Up @@ -1399,7 +1408,7 @@ private TypeSymbol ComputeType(Binder binder, BasePropertyDeclarationSyntax synt
private ImmutableArray<ParameterSymbol> ComputeParameters(Binder binder, BasePropertyDeclarationSyntax syntax, DiagnosticBag diagnostics)
{
var parameterSyntaxOpt = GetParameterListSyntax(syntax);
var parameters = MakeParameters(binder, this, parameterSyntaxOpt, diagnostics);
var parameters = MakeParameters(binder, this, parameterSyntaxOpt, diagnostics, addIsConstModifier: IsVirtual || IsAbstract);
HashSet<DiagnosticInfo> useSiteDiagnostics = null;

foreach (ParameterSymbol param in parameters)
Expand Down
Loading

0 comments on commit 55d359d

Please sign in to comment.