提交 643f18a8 编写于 作者: C CyrusNajmabadi

Merge remote-tracking branch 'upstream/post-dev15' into parserDiagnostics9

......@@ -265,7 +265,10 @@ protected virtual bool IsAttributeConditionallyOmitted(NamedTypeSymbol attribute
}
}
private AnalyzedAttributeArguments BindAttributeArguments(AttributeArgumentListSyntax attributeArgumentList, NamedTypeSymbol attributeType, DiagnosticBag diagnostics)
private AnalyzedAttributeArguments BindAttributeArguments(
AttributeArgumentListSyntax attributeArgumentList,
NamedTypeSymbol attributeType,
DiagnosticBag diagnostics)
{
var boundConstructorArguments = AnalyzedArguments.GetInstance();
var boundNamedArguments = ImmutableArray<BoundExpression>.Empty;
......@@ -279,10 +282,17 @@ private AnalyzedAttributeArguments BindAttributeArguments(AttributeArgumentListS
// matching Dev10 compiler behavior.
bool hadError = false;
var shouldHaveName = false;
foreach (var argument in attributeArgumentList.Arguments)
{
if (argument.NameEquals == null)
{
if (shouldHaveName)
{
diagnostics.Add(ErrorCode.ERR_NamedArgumentExpected, argument.Expression.GetLocation());
}
// Constructor argument
hadError |= this.BindArgumentAndName(
boundConstructorArguments,
......@@ -302,6 +312,8 @@ private AnalyzedAttributeArguments BindAttributeArguments(AttributeArgumentListS
}
else
{
shouldHaveName = true;
// Named argument
// TODO: use fully qualified identifier name for boundNamedArgumentsSet
string argumentName = argument.NameEquals.Name.Identifier.ValueText;
......
......@@ -94,6 +94,11 @@ internal partial class Binder
foreach (var p in parameterSyntaxList.Value)
{
foreach (var attributeList in p.AttributeLists)
{
Error(diagnostics, ErrorCode.ERR_AttributesNotAllowed, attributeList);
}
if (p.IsArgList)
{
Error(diagnostics, ErrorCode.ERR_IllegalVarArgs, p);
......
......@@ -382,8 +382,7 @@ private void EmitLoweredConditionalAccessExpression(BoundLoweredConditionalAcces
// or if we have default(T) (to do box just once)
var nullCheckOnCopy = LocalRewriter.CanChangeValueBetweenReads(receiver, localsMayBeAssignedOrCaptured: false) ||
(receiverType.IsReferenceType && receiverType.TypeKind == TypeKind.TypeParameter) ||
(receiver.Kind == BoundKind.Local && IsStackLocal(((BoundLocal)receiver).LocalSymbol)) ||
(receiver.IsDefaultValue() && unconstrainedReceiver);
(receiver.Kind == BoundKind.Local && IsStackLocal(((BoundLocal)receiver).LocalSymbol));
// ===== RECEIVER
if (nullCheckOnCopy)
......@@ -492,7 +491,7 @@ private void EmitLoweredConditionalAccessExpression(BoundLoweredConditionalAcces
{
Debug.Assert(receiverTemp == null);
receiverTemp = EmitReceiverRef(receiver, isAccessConstrained: unconstrainedReceiver);
Debug.Assert(receiverTemp == null);
Debug.Assert(receiverTemp == null || receiver.IsDefaultValue());
}
EmitExpression(expression.WhenNotNull, used);
......
......@@ -1481,9 +1481,21 @@ private static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationSta
var sourceMethod = method as SourceMethodSymbol;
if ((object)sourceMethod != null)
{
var constructorSyntax = sourceMethod.SyntaxNode as ConstructorDeclarationSyntax;
// Static constructor can't have any this/base call
if (method.MethodKind == MethodKind.StaticConstructor &&
constructorSyntax?.Initializer != null)
{
diagnostics.Add(
ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall,
constructorSyntax.Initializer.ThisOrBaseKeyword.GetLocation(),
constructorSyntax.Identifier.ValueText);
}
if (sourceMethod.IsExtern)
{
if (sourceMethod.BodySyntax == null && (sourceMethod.SyntaxNode as ConstructorDeclarationSyntax)?.Initializer == null)
if (sourceMethod.BodySyntax == null && constructorSyntax?.Initializer == null)
{
// Generate warnings only if we are not generating ERR_ExternHasBody or ERR_ExternHasConstructorInitializer errors
GenerateExternalMethodWarnings(sourceMethod, diagnostics);
......@@ -1597,7 +1609,8 @@ private static BoundStatement BindConstructorInitializerIfAny(MethodSymbol metho
/// <param name="diagnostics">Accumulates errors (e.g. access "this" in constructor initializer).</param>
/// <param name="compilation">Used to retrieve binder.</param>
/// <returns>A bound expression for the constructor initializer call.</returns>
internal static BoundExpression BindConstructorInitializer(MethodSymbol constructor, DiagnosticBag diagnostics, CSharpCompilation compilation)
internal static BoundExpression BindConstructorInitializer(
MethodSymbol constructor, DiagnosticBag diagnostics, CSharpCompilation compilation)
{
// Note that the base type can be null if we're compiling System.Object in source.
NamedTypeSymbol baseType = constructor.ContainingType.BaseTypeNoUseSiteDiagnostics;
......
......@@ -956,19 +956,14 @@ private bool IsPossibleAttributeDeclaration()
return this.CurrentToken.Kind == SyntaxKind.OpenBracketToken;
}
private void ParseAttributeDeclarations(SyntaxListBuilder list, bool allowAttributes = true)
private void ParseAttributeDeclarations(SyntaxListBuilder list)
{
var saveTerm = _termState;
_termState |= TerminatorState.IsAttributeDeclarationTerminator;
while (this.IsPossibleAttributeDeclaration())
{
var section = this.ParseAttributeDeclaration();
if (!allowAttributes)
{
section = this.AddError(section, ErrorCode.ERR_AttributesNotAllowed);
}
list.Add(section);
list.Add(this.ParseAttributeDeclaration());
}
_termState = saveTerm;
......@@ -1094,14 +1089,13 @@ internal AttributeArgumentListSyntax ParseAttributeArgumentList()
var argNodes = _pool.AllocateSeparated<AttributeArgumentSyntax>();
try
{
bool shouldHaveName = false;
tryAgain:
if (this.CurrentToken.Kind != SyntaxKind.CloseParenToken)
{
if (this.IsPossibleAttributeArgument() || this.CurrentToken.Kind == SyntaxKind.CommaToken)
{
// first argument
argNodes.Add(this.ParseAttributeArgument(ref shouldHaveName));
argNodes.Add(this.ParseAttributeArgument());
// comma + argument or end?
while (true)
......@@ -1113,7 +1107,7 @@ internal AttributeArgumentListSyntax ParseAttributeArgumentList()
else if (this.CurrentToken.Kind == SyntaxKind.CommaToken || this.IsPossibleAttributeArgument())
{
argNodes.AddSeparator(this.EatToken(SyntaxKind.CommaToken));
argNodes.Add(this.ParseAttributeArgument(ref shouldHaveName));
argNodes.Add(this.ParseAttributeArgument());
}
else if (this.SkipBadAttributeArgumentTokens(ref openParen, argNodes, SyntaxKind.CommaToken) == PostSkipAction.Abort)
{
......@@ -1152,7 +1146,7 @@ private bool IsPossibleAttributeArgument()
return this.IsPossibleExpression();
}
private AttributeArgumentSyntax ParseAttributeArgument(ref bool shouldHaveName)
private AttributeArgumentSyntax ParseAttributeArgument()
{
// Need to parse both "real" named arguments and attribute-style named arguments.
// We track attribute-style named arguments only with fShouldHaveName.
......@@ -1169,7 +1163,6 @@ private AttributeArgumentSyntax ParseAttributeArgument(ref bool shouldHaveName)
var name = this.ParseIdentifierToken();
var equals = this.EatToken(SyntaxKind.EqualsToken);
nameEquals = _syntaxFactory.NameEquals(_syntaxFactory.IdentifierName(name), equals);
shouldHaveName = true;
}
break;
......@@ -1180,20 +1173,12 @@ private AttributeArgumentSyntax ParseAttributeArgument(ref bool shouldHaveName)
nameColon = _syntaxFactory.NameColon(name, colonToken);
nameColon = CheckFeatureAvailability(nameColon, MessageID.IDS_FeatureNamedArgument);
}
break;
}
}
var expr = this.ParseExpressionCore();
// Not named -- give an error if it's supposed to be
if (shouldHaveName && nameEquals == null)
{
expr = this.AddError(expr, ErrorCode.ERR_NamedArgumentExpected);
}
return _syntaxFactory.AttributeArgument(nameEquals, nameColon, expr);
return _syntaxFactory.AttributeArgument(
nameEquals, nameColon, this.ParseExpressionCore());
}
[Flags]
......@@ -2666,7 +2651,8 @@ public static bool IsComplete(CSharpSyntaxNode node)
return true;
}
private ConstructorDeclarationSyntax ParseConstructorDeclaration(string typeName, SyntaxListBuilder<AttributeListSyntax> attributes, SyntaxListBuilder modifiers)
private ConstructorDeclarationSyntax ParseConstructorDeclaration(
string typeName, SyntaxListBuilder<AttributeListSyntax> attributes, SyntaxListBuilder modifiers)
{
var name = this.ParseIdentifierToken();
Debug.Assert(name.ValueText == typeName);
......@@ -2675,20 +2661,15 @@ private ConstructorDeclarationSyntax ParseConstructorDeclaration(string typeName
_termState |= TerminatorState.IsEndOfMethodSignature;
try
{
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true);
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true);
ConstructorInitializerSyntax initializer = null;
if (this.CurrentToken.Kind == SyntaxKind.ColonToken)
{
bool isStatic = modifiers != null && modifiers.Any((int)SyntaxKind.StaticKeyword);
initializer = this.ParseConstructorInitializer(name.ValueText, isStatic);
}
ConstructorInitializerSyntax initializer = this.CurrentToken.Kind == SyntaxKind.ColonToken
? this.ParseConstructorInitializer()
: null;
BlockSyntax body;
ArrowExpressionClauseSyntax expressionBody;
SyntaxToken semicolon;
this.ParseBlockAndExpressionBodiesWithSemicolon(out body, out expressionBody, out semicolon,
requestedExpressionBodyFeature: MessageID.IDS_FeatureExpressionBodiedDeOrConstructor);
this.ParseBlockAndExpressionBodiesWithSemicolon(
out BlockSyntax body, out ArrowExpressionClauseSyntax expressionBody, out SyntaxToken semicolon,
requestedExpressionBodyFeature: MessageID.IDS_FeatureExpressionBodiedDeOrConstructor);
var decl = _syntaxFactory.ConstructorDeclaration(attributes, modifiers.ToList(), name, paramList, initializer, body, expressionBody, semicolon);
return CheckForBlockAndExpressionBody(body, expressionBody, decl);
......@@ -2699,7 +2680,7 @@ private ConstructorDeclarationSyntax ParseConstructorDeclaration(string typeName
}
}
private ConstructorInitializerSyntax ParseConstructorInitializer(string name, bool isStatic)
private ConstructorInitializerSyntax ParseConstructorInitializer()
{
var colon = this.EatToken(SyntaxKind.ColonToken);
......@@ -2733,12 +2714,6 @@ private ConstructorInitializerSyntax ParseConstructorInitializer(string name, bo
argumentList = _syntaxFactory.ArgumentList(openToken, default(SeparatedSyntaxList<ArgumentSyntax>), closeToken);
}
if (isStatic)
{
// Static constructor can't have any base call
token = this.AddError(token, ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall, name);
}
return _syntaxFactory.ConstructorInitializer(kind, colon, token, argumentList);
}
......@@ -2920,7 +2895,7 @@ private bool IsEndOfNameInExplicitInterface()
var saveTerm = _termState;
_termState |= TerminatorState.IsEndOfMethodSignature;
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true, allowAttributes: true);
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true);
var constraints = default(SyntaxListBuilder<TypeParameterConstraintClauseSyntax>);
try
......@@ -2934,8 +2909,8 @@ private bool IsEndOfNameInExplicitInterface()
{
// Use else if, rather than if, because if we see both a constructor initializer and a constraint clause, we're too lost to recover.
var colonToken = this.CurrentToken;
// Set isStatic to false because pretending we're in a static constructor will just result in more errors.
ConstructorInitializerSyntax initializer = this.ParseConstructorInitializer(identifier.ValueText, isStatic: false);
ConstructorInitializerSyntax initializer = this.ParseConstructorInitializer();
initializer = this.AddErrorToFirstToken(initializer, ErrorCode.ERR_UnexpectedToken, colonToken.Text);
paramList = AddTrailingSkippedSyntax(paramList, initializer);
......@@ -3035,7 +3010,7 @@ private ConversionOperatorDeclarationSyntax ParseConversionOperatorDeclaration(S
var type = this.ParseType();
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true);
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true);
if (paramList.Parameters.Count != 1)
{
paramList = this.AddErrorToFirstToken(paramList, ErrorCode.ERR_OvlUnaryOperatorExpected);
......@@ -3123,7 +3098,7 @@ private ConversionOperatorDeclarationSyntax ParseConversionOperatorDeclaration(S
}
}
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true);
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true);
switch (paramList.Parameters.Count)
{
......@@ -3800,7 +3775,7 @@ private bool CanReuseAccessorDeclaration(bool isEvent)
return false;
}
internal ParameterListSyntax ParseParenthesizedParameterList(bool allowThisKeyword, bool allowDefaults, bool allowAttributes)
internal ParameterListSyntax ParseParenthesizedParameterList(bool allowThisKeyword, bool allowDefaults)
{
if (this.IsIncrementalAndFactoryContextMatches && CanReuseParameterList(this.CurrentNode as CSharp.Syntax.ParameterListSyntax))
{
......@@ -3816,7 +3791,7 @@ internal ParameterListSyntax ParseParenthesizedParameterList(bool allowThisKeywo
SyntaxToken open;
SyntaxToken close;
this.ParseParameterList(out open, parameters, out close, openKind, closeKind, allowThisKeyword, allowDefaults, allowAttributes);
this.ParseParameterList(out open, parameters, out close, openKind, closeKind, allowThisKeyword, allowDefaults);
return _syntaxFactory.ParameterList(open, parameters, close);
}
finally
......@@ -3841,7 +3816,7 @@ internal BracketedParameterListSyntax ParseBracketedParameterList(bool allowDefa
SyntaxToken open;
SyntaxToken close;
this.ParseParameterList(out open, parameters, out close, openKind, closeKind, allowThisKeyword: false, allowDefaults: allowDefaults, allowAttributes: true);
this.ParseParameterList(out open, parameters, out close, openKind, closeKind, allowThisKeyword: false, allowDefaults: allowDefaults);
return _syntaxFactory.BracketedParameterList(open, parameters, close);
}
finally
......@@ -3913,8 +3888,7 @@ private static bool CanReuseBracketedParameterList(CSharp.Syntax.BracketedParame
SyntaxKind openKind,
SyntaxKind closeKind,
bool allowThisKeyword,
bool allowDefaults,
bool allowAttributes)
bool allowDefaults)
{
open = this.EatToken(openKind);
......@@ -3938,7 +3912,7 @@ private static bool CanReuseBracketedParameterList(CSharp.Syntax.BracketedParame
// first parameter
attributes.Clear();
modifiers.Clear();
var parameter = this.ParseParameter(attributes, modifiers, allowThisKeyword, allowDefaults, allowAttributes);
var parameter = this.ParseParameter(attributes, modifiers, allowThisKeyword, allowDefaults);
nodes.Add(parameter);
hasParams = modifiers.Any((int)SyntaxKind.ParamsKeyword);
hasArgList = parameter.Identifier.Kind == SyntaxKind.ArgListKeyword;
......@@ -3961,7 +3935,7 @@ private static bool CanReuseBracketedParameterList(CSharp.Syntax.BracketedParame
nodes.AddSeparator(this.EatToken(SyntaxKind.CommaToken));
attributes.Clear();
modifiers.Clear();
parameter = this.ParseParameter(attributes, modifiers, allowThisKeyword, allowDefaults, allowAttributes);
parameter = this.ParseParameter(attributes, modifiers, allowThisKeyword, allowDefaults);
if (parameter.IsMissing && this.IsPossibleParameter(allowThisKeyword))
{
// ensure we always consume tokens
......@@ -4101,15 +4075,14 @@ private static bool CanReuseParameter(CSharp.Syntax.ParameterSyntax parameter)
SyntaxListBuilder<AttributeListSyntax> attributes,
SyntaxListBuilder modifiers,
bool allowThisKeyword,
bool allowDefaults,
bool allowAttributes)
bool allowDefaults)
{
if (this.IsIncrementalAndFactoryContextMatches && CanReuseParameter(this.CurrentNode as CSharp.Syntax.ParameterSyntax, attributes, modifiers))
{
return (ParameterSyntax)this.EatNode();
}
this.ParseAttributeDeclarations(attributes, allowAttributes);
this.ParseAttributeDeclarations(attributes);
this.ParseParameterModifiers(modifiers, allowThisKeyword);
var hasArgList = this.CurrentToken.Kind == SyntaxKind.ArgListKeyword;
......@@ -4987,7 +4960,7 @@ private bool IsLocalFunctionAfterIdentifier()
{
var typeParameterListOpt = this.ParseTypeParameterList();
var paramList = ParseParenthesizedParameterList(
allowThisKeyword: true, allowDefaults: true, allowAttributes: true);
allowThisKeyword: true, allowDefaults: true);
if (!paramList.IsMissing &&
(this.CurrentToken.Kind == SyntaxKind.OpenBraceToken ||
......@@ -5079,7 +5052,7 @@ private DelegateDeclarationSyntax ParseDelegateDeclaration(SyntaxListBuilder<Att
_termState |= TerminatorState.IsEndOfMethodSignature;
var name = this.ParseIdentifierToken();
var typeParameters = this.ParseTypeParameterList();
var parameterList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true);
var parameterList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true);
var constraints = default(SyntaxListBuilder<TypeParameterConstraintClauseSyntax>);
try
{
......@@ -7154,7 +7127,7 @@ private bool IsPossibleMethodDeclarationFollowingNullableType()
var saveTerm = _termState;
_termState |= TerminatorState.IsEndOfMethodSignature;
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true, allowAttributes: true);
var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true);
_termState = saveTerm;
var separatedParameters = paramList.Parameters.GetWithSeparators();
......@@ -8842,7 +8815,7 @@ private static bool IsAccessibilityModifier(SyntaxKind kind)
TypeParameterListSyntax typeParameterListOpt = this.ParseTypeParameterList();
// "await f<T>()" still makes sense, so don't force accept a local function if there's a type parameter list.
ParameterListSyntax paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true, allowAttributes: true);
ParameterListSyntax paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true);
// "await x()" is ambiguous (see note at start of this method), but we assume "await x(await y)" is meant to be a function if it's in a non-async context.
if (!forceLocalFunc)
{
......@@ -11103,7 +11076,7 @@ private AnonymousMethodExpressionSyntax ParseAnonymousMethodExpression()
ParameterListSyntax parameterList = null;
if (this.CurrentToken.Kind == SyntaxKind.OpenParenToken)
{
parameterList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: false, allowAttributes: false);
parameterList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: false);
}
// In mismatched braces cases (missing a }) it is possible for delegate declarations to be
......
......@@ -344,6 +344,11 @@ private ImmutableArray<TypeParameterSymbol> MakeTypeParameters(DiagnosticBag dia
for (int ordinal = 0; ordinal < typeParameters.Count; ordinal++)
{
var parameter = typeParameters[ordinal];
if (parameter.VarianceKeyword.Kind() != SyntaxKind.None)
{
diagnostics.Add(ErrorCode.ERR_IllegalVarianceSyntax, parameter.VarianceKeyword.GetLocation());
}
var identifier = parameter.Identifier;
var location = identifier.GetLocation();
var name = identifier.ValueText;
......
......@@ -1816,7 +1816,7 @@ public static ParameterListSyntax ParseParameterList(string text, int offset = 0
using (var lexer = MakeLexer(text, offset, (CSharpParseOptions)options))
using (var parser = MakeParser(lexer))
{
var node = parser.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true, allowAttributes: true);
var node = parser.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true);
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
return (ParameterListSyntax)node.CreateRed();
}
......
......@@ -6924,37 +6924,29 @@ static void Main()
verifier.VerifyIL("Test<T>.Run", @"
{
// Code size 65 (0x41)
.maxstack 2
// Code size 48 (0x30)
.maxstack 1
.locals init (T V_0,
T V_1,
string V_2)
string V_1)
IL_0000: nop
IL_0001: ldloca.s V_0
IL_0003: initobj ""T""
IL_0009: ldloc.0
IL_000a: stloc.0
IL_000b: ldloca.s V_0
IL_000d: ldloca.s V_1
IL_000f: initobj ""T""
IL_0015: ldloc.1
IL_0016: box ""T""
IL_001b: brtrue.s IL_0031
IL_001d: ldobj ""T""
IL_0022: stloc.1
IL_0023: ldloca.s V_1
IL_0025: ldloc.1
IL_0026: box ""T""
IL_002b: brtrue.s IL_0031
IL_002d: pop
IL_002e: ldnull
IL_002f: br.s IL_003c
IL_0031: constrained. ""T""
IL_0037: callvirt ""string object.ToString()""
IL_003c: stloc.2
IL_003d: br.s IL_003f
IL_003f: ldloc.2
IL_0040: ret
IL_000a: box ""T""
IL_000f: brtrue.s IL_0014
IL_0011: ldnull
IL_0012: br.s IL_002b
IL_0014: ldloca.s V_0
IL_0016: initobj ""T""
IL_001c: ldloc.0
IL_001d: stloc.0
IL_001e: ldloca.s V_0
IL_0020: constrained. ""T""
IL_0026: callvirt ""string object.ToString()""
IL_002b: stloc.1
IL_002c: br.s IL_002e
IL_002e: ldloc.1
IL_002f: ret
}");
}
......@@ -7051,37 +7043,29 @@ static void Main()
verifier.VerifyIL("Test<T>.Run", @"
{
// Code size 65 (0x41)
.maxstack 2
// Code size 48 (0x30)
.maxstack 1
.locals init (T V_0,
T V_1,
string V_2)
string V_1)
IL_0000: nop
IL_0001: ldloca.s V_0
IL_0003: initobj ""T""
IL_0009: ldloc.0
IL_000a: stloc.0
IL_000b: ldloca.s V_0
IL_000d: ldloca.s V_1
IL_000f: initobj ""T""
IL_0015: ldloc.1
IL_0016: box ""T""
IL_001b: brtrue.s IL_0031
IL_001d: ldobj ""T""
IL_0022: stloc.1
IL_0023: ldloca.s V_1
IL_0025: ldloc.1
IL_0026: box ""T""
IL_002b: brtrue.s IL_0031
IL_002d: pop
IL_002e: ldnull
IL_002f: br.s IL_003c
IL_0031: constrained. ""T""
IL_0037: callvirt ""string object.ToString()""
IL_003c: stloc.2
IL_003d: br.s IL_003f
IL_003f: ldloc.2
IL_0040: ret
IL_000a: box ""T""
IL_000f: brtrue.s IL_0014
IL_0011: ldnull
IL_0012: br.s IL_002b
IL_0014: ldloca.s V_0
IL_0016: initobj ""T""
IL_001c: ldloc.0
IL_001d: stloc.0
IL_001e: ldloca.s V_0
IL_0020: constrained. ""T""
IL_0026: callvirt ""string object.ToString()""
IL_002b: stloc.1
IL_002c: br.s IL_002e
IL_002e: ldloc.1
IL_002f: ret
}");
}
......
......@@ -667,7 +667,13 @@ public class cly : clx
}
";
ParseAndValidate(test, Diagnostic(ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall, "base").WithArguments("cly"));
CreateCompilationWithMscorlib(test).VerifyDiagnostics(
// (12,24): error CS0514: 'cly': static constructor cannot have an explicit 'this' or 'base' constructor call
// static cly() : base(0){} // sc0514
Diagnostic(ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall, "base").WithArguments("cly").WithLocation(12, 24),
// (8,18): error CS7036: There is no argument given that corresponds to the required formal parameter 'i' of 'clx.clx(int)'
// public class cly : clx
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "cly").WithArguments("i", "x.clx.clx(int)").WithLocation(8, 18));
}
[Fact]
......@@ -681,7 +687,10 @@ class C
}
";
ParseAndValidate(test, Diagnostic(ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall, "this").WithArguments("C"));
CreateCompilationWithMscorlib(test).VerifyDiagnostics(
// (5,18): error CS0514: 'C': static constructor cannot have an explicit 'this' or 'base' constructor call
// static C() : this() { } //CS0514
Diagnostic(ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall, "this").WithArguments("C").WithLocation(5, 18));
}
[Fact]
......@@ -1647,21 +1656,30 @@ public void CS1016ERR_NamedArgumentExpected()
var test = @"
namespace x
{
[foo(a=5, b)]
class foo
class FooAttribute : System.Attribute
{
public int a;
}
public class a
[Foo(a=5, b)]
class Bar
{
public static int Main()
}
public class a
{
public static int Main()
{
return 1;
return 1;
}
}
}
";
ParseAndValidate(test, Diagnostic(ErrorCode.ERR_NamedArgumentExpected, "b"));
}";
CreateCompilationWithMscorlib(test).VerifyDiagnostics(
// (9,15): error CS1016: Named attribute argument expected
// [Foo(a=5, b)]
Diagnostic(ErrorCode.ERR_NamedArgumentExpected, "b").WithLocation(9, 15),
// (9,15): error CS0103: The name 'b' does not exist in the current context
// [Foo(a=5, b)]
Diagnostic(ErrorCode.ERR_NameNotInContext, "b").WithArguments("b").WithLocation(9, 15));
}
[Fact]
......@@ -2566,8 +2584,7 @@ class A
ParseAndValidate(test, Diagnostic(ErrorCode.ERR_DefaultValueNotAllowed, "="));
}
[WorkItem(540251, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540251")]
[Fact]
[Fact, WorkItem(540251, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540251")]
public void CS7014ERR_AttributesNotAllowed()
{
var test = @"
......@@ -2578,7 +2595,7 @@ class Program
static void Main()
{
const string message = ""the parameter is obsolete"";
Action<int> a = delegate (
Action<int, int> a = delegate (
[ObsoleteAttribute(message)] [ObsoleteAttribute(message)] int x,
[ObsoleteAttribute(message)] int y
) { };
......@@ -2586,16 +2603,19 @@ static void Main()
}
";
ParseAndValidate(test,
// (10,13): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] [ObsoleteAttribute(message)] int x,
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]"),
// (10,42): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] [ObsoleteAttribute(message)] int x,
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]"),
// (11,13): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] int y
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]"));
CreateCompilationWithMscorlib(test).VerifyDiagnostics(
// (10,13): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] [ObsoleteAttribute(message)] int x,
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]").WithLocation(10, 13),
// (10,42): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] [ObsoleteAttribute(message)] int x,
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]").WithLocation(10, 42),
// (11,13): error CS7014: Attributes are not valid in this context.
// [ObsoleteAttribute(message)] int y
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[ObsoleteAttribute(message)]").WithLocation(11, 13),
// (8,22): warning CS0219: The variable 'message' is assigned but its value is never used
// const string message = "the parameter is obsolete";
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "message").WithArguments("message").WithLocation(8, 22));
}
[WorkItem(863401, "DevDiv/Personal")]
......
......@@ -366,7 +366,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
If Not nullCheckOnCopy Then
receiverTemp = EmitReceiverRef(receiver, isAccessConstrained:=Not receiverType.IsReferenceType, addressKind:=AddressKind.ReadOnly)
Debug.Assert(receiverTemp Is Nothing)
Debug.Assert(receiverTemp Is Nothing OrElse receiver.IsDefaultValue())
End If
EmitExpression(conditional.WhenNotNull, used)
......
......@@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return DirectCast(receiver, BoundLocal).LocalSymbol.IsByRef
Case Else
Return True
Return Not receiver.IsDefaultValue()
End Select
End Function
......
......@@ -13618,6 +13618,51 @@ IL_0006: callvirt "Function MainModule.Form1.BadCompiler.get_Value() As Date?
IL_000b: pop
IL_000c: ret
}
]]>)
End Sub
<Fact, WorkItem(15672, "https://github.com/dotnet/roslyn/pull/15672")>
Public Sub ConditionalAccessOffOfUnconstrainedDefault1()
Dim c = CompileAndVerify(
<compilation>
<file name="ignoreNullableValue.vb">
Module Module1
Public Sub Main()
Test(42)
Test("")
End Sub
Public Sub Test(of T)(arg as T)
System.Console.WriteLine(DirectCast(Nothing, T)?.ToString())
End Sub
End Module
</file>
</compilation>, options:=TestOptions.ReleaseExe,
expectedOutput:="0")
c.VerifyIL("Module1.Test",
<![CDATA[
{
// Code size 48 (0x30)
.maxstack 1
.locals init (T V_0)
IL_0000: ldloca.s V_0
IL_0002: initobj "T"
IL_0008: ldloc.0
IL_0009: box "T"
IL_000e: brtrue.s IL_0013
IL_0010: ldnull
IL_0011: br.s IL_002a
IL_0013: ldloca.s V_0
IL_0015: initobj "T"
IL_001b: ldloc.0
IL_001c: stloc.0
IL_001d: ldloca.s V_0
IL_001f: constrained. "T"
IL_0025: callvirt "Function Object.ToString() As String"
IL_002a: call "Sub System.Console.WriteLine(String)"
IL_002f: ret
}
]]>)
End Sub
End Class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册