From 80721b4553bb1a0682f41f285a507a1cc877aa29 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 17 Dec 2018 13:05:19 -0800 Subject: [PATCH] Update ManagedAddr binder checks to require CSharp8 for unmanaged generic structs --- .../Portable/Binder/Binder_Expressions.cs | 49 ++++++++++++++++--- .../Portable/Binder/Binder_Operators.cs | 19 +++++-- .../Portable/Binder/Binder_Statements.cs | 10 ++++ .../CSharp/Portable/Binder/Binder_Symbols.cs | 13 +++-- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 90976e30df0a1..be9f4dbaeebc0 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -1132,10 +1132,23 @@ private BoundExpression BindSizeOf(SizeOfExpressionSyntax node, DiagnosticBag di bool typeHasErrors = type.IsErrorType(); - if (!typeHasErrors && type.IsManagedType) + if (!typeHasErrors) { - diagnostics.Add(ErrorCode.ERR_ManagedAddr, node.Location, type); - typeHasErrors = true; + if (type.IsManagedType) + { + diagnostics.Add(ErrorCode.ERR_ManagedAddr, typeSyntax.Location, type); + typeHasErrors = true; + } + else if (type.GetArity() != 0) + { + var unsupported = Compilation.LanguageVersion < MessageID.IDS_FeatureUnmanagedGenericStructs.RequiredVersion(); + if (unsupported) + { + // PROTOTYPE + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, typeSyntax.Location); + typeHasErrors = true; + } + } } BoundTypeExpression boundType = new BoundTypeExpression(typeSyntax, alias, type, typeHasErrors); @@ -2870,9 +2883,16 @@ private BoundExpression BindImplicitStackAllocArrayCreationExpression(ImplicitSt bestType = CreateErrorType(); } - if (!bestType.IsErrorType() && bestType.IsManagedType) + if (!bestType.IsErrorType()) { - Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, bestType); + if (bestType.IsManagedType) + { + Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, bestType); + } + else if (bestType.GetArity() != 0) + { + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, node.Location); + } } return BindStackAllocWithInitializer( @@ -3223,10 +3243,23 @@ private BoundExpression BindStackAllocArrayCreationExpression( var elementType = BindType(elementTypeSyntax, diagnostics); TypeSymbol type = GetStackAllocType(node, elementType, diagnostics, out bool hasErrors); - if (!elementType.IsErrorType() && elementType.IsManagedType) + if (!elementType.IsErrorType()) { - Error(diagnostics, ErrorCode.ERR_ManagedAddr, elementTypeSyntax, elementType.TypeSymbol); - hasErrors = true; + if (elementType.IsManagedType) + { + Error(diagnostics, ErrorCode.ERR_ManagedAddr, elementTypeSyntax, elementType.TypeSymbol); + hasErrors = true; + } + else if (elementType.TypeSymbol.GetArity() != 0) + { + var unsupported = Compilation.LanguageVersion < MessageID.IDS_FeatureUnmanagedGenericStructs.RequiredVersion(); + if (unsupported) + { + // PROTOTYPE + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, elementTypeSyntax.Location); + hasErrors = true; + } + } } SyntaxList rankSpecifiers = arrayTypeSyntax.RankSpecifiers; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs index fac79146f0a33..47bdc6b12ffaf 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs @@ -2131,10 +2131,23 @@ private BoundExpression BindAddressOfExpression(PrefixUnaryExpressionSyntax node bool allowManagedAddressOf = Flags.Includes(BinderFlags.AllowManagedAddressOf); if (!allowManagedAddressOf) { - if (!hasErrors && isManagedType) + if (!hasErrors) { - hasErrors = true; - Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, operandType); + if (isManagedType) + { + hasErrors = true; + Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, operandType); + } + else if (operandType.GetArity() != 0) + { + var supported = MessageID.IDS_FeatureUnmanagedGenericStructs.RequiredVersion() >= Compilation.LanguageVersion; + if (!supported) + { + // PROTOTYPE + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, node.Location); + hasErrors = true; + } + } } if (!hasErrors) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 4a8ff5348bebf..9b4f29e30cf40 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -1167,6 +1167,16 @@ private bool IsValidFixedVariableInitializer(TypeSymbol declType, SourceLocalSym Error(diagnostics, ErrorCode.ERR_ManagedAddr, initializerSyntax, elementType); hasErrors = true; } + else if (elementType.GetArity() != 0) + { + var supported = MessageID.IDS_FeatureUnmanagedGenericStructs.RequiredVersion() >= Compilation.LanguageVersion; + if (!supported) + { + // PROTOTYPE + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, initializerSyntax.Location); + hasErrors = true; + } + } initializerOpt = GetFixedLocalCollectionInitializer(initializerOpt, elementType, declType, fixedPatternMethod, hasErrors, diagnostics); return true; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index e804c3918a752..62a634a279ed3 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -465,10 +465,17 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS // Invalid constraint type. A type used as a constraint must be an interface, a non-sealed class or a type parameter. Error(diagnostics, ErrorCode.ERR_BadConstraintType, node); } - else if (elementType.IsManagedType) + else { - // "Cannot take the address of, get the size of, or declare a pointer to a managed type ('{0}')" - Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, elementType.TypeSymbol); + if (elementType.IsManagedType) + { + // "Cannot take the address of, get the size of, or declare a pointer to a managed type ('{0}')" + Error(diagnostics, ErrorCode.ERR_ManagedAddr, node, elementType.TypeSymbol); + } + else if (elementType.TypeSymbol.GetArity() != 0) + { + MessageID.IDS_FeatureUnmanagedGenericStructs.CheckFeatureAvailability(Compilation.LanguageVersion, diagnostics, syntax.Location); + } } return TypeSymbolWithAnnotations.Create(new PointerTypeSymbol(elementType));