提交 19b00627 编写于 作者: N nmgafter

1112822-Color Color versus const initializer cycles (changeset 1409657)

上级 131c88d6
......@@ -1052,7 +1052,7 @@ private BoundExpression BindNonMethod(SimpleNameSyntax node, Symbol symbol, Diag
case SymbolKind.Local:
{
var localSymbol = (LocalSymbol)symbol;
var constantValueOpt = localSymbol.IsConst ? localSymbol.GetConstantValue(this.LocalInProgress) : null;
var constantValueOpt = localSymbol.IsConst ? localSymbol.GetConstantValue(node, this.LocalInProgress, diagnostics) : null;
TypeSymbol type;
Location localSymbolLocation = localSymbol.Locations[0];
......
......@@ -682,6 +682,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
Debug.Assert((object)declTypeOpt != null || isVar);
Debug.Assert(typeSyntax != null);
var localDiagnostics = DiagnosticBag.GetInstance();
// if we are not given desired syntax, we use declarator
associatedSyntaxNode = associatedSyntaxNode ?? declarator;
......@@ -690,7 +691,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
BoundExpression initializerOpt;
// Check for variable declaration errors.
hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);
hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, localDiagnostics);
EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer;
if (isVar)
......@@ -698,7 +699,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
aliasOpt = null;
var binder = new ImplicitlyTypedLocalBinder(this, localSymbol);
initializerOpt = binder.BindInferredVariableInitializer(diagnostics, equalsValueClauseSyntax, declarator);
initializerOpt = binder.BindInferredVariableInitializer(localDiagnostics, equalsValueClauseSyntax, declarator);
// If we got a good result then swap the inferred type for the "var"
if ((object)initializerOpt?.Type != null)
......@@ -707,7 +708,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
if (declTypeOpt.SpecialType == SpecialType.System_Void)
{
Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt);
Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt);
declTypeOpt = CreateErrorType("var");
hasErrors = true;
}
......@@ -716,7 +717,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
{
if (declTypeOpt.IsStatic)
{
Error(diagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type);
Error(localDiagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type);
hasErrors = true;
}
}
......@@ -736,11 +737,11 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
else
{
// Basically inlined BindVariableInitializer, but with conversion optional.
initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, diagnostics);
initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, localDiagnostics);
if (kind != LocalDeclarationKind.FixedVariable)
{
// If this is for a fixed statement, we'll do our own conversion since there are some special cases.
initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, diagnostics);
initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, localDiagnostics);
}
}
}
......@@ -754,7 +755,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
{
if (!hasErrors)
{
Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator);
Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator);
hasErrors = true;
}
}
......@@ -763,11 +764,11 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
{
if (!hasErrors)
{
Error(diagnostics, ErrorCode.ERR_BadFixedInitType, declarator);
Error(localDiagnostics, ErrorCode.ERR_BadFixedInitType, declarator);
hasErrors = true;
}
}
else if (!IsValidFixedVariableInitializer(declTypeOpt, localSymbol, ref initializerOpt, diagnostics))
else if (!IsValidFixedVariableInitializer(declTypeOpt, localSymbol, ref initializerOpt, localDiagnostics))
{
hasErrors = true;
}
......@@ -777,7 +778,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
&& ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync
&& declTypeOpt.IsRestrictedType())
{
Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declTypeOpt);
Error(localDiagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declTypeOpt);
hasErrors = true;
}
......@@ -788,7 +789,7 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
Debug.Assert((object)localSymbol != null);
ImmutableArray<BoundExpression> arguments = BindDeclaratorArguments(declarator, diagnostics);
ImmutableArray<BoundExpression> arguments = BindDeclaratorArguments(declarator, localDiagnostics);
if (kind == LocalDeclarationKind.FixedVariable || kind == LocalDeclarationKind.UsingVariable)
{
......@@ -799,19 +800,21 @@ private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, Diagnostic
if (initializerOpt == null)
{
Error(diagnostics, ErrorCode.ERR_FixedMustInit, declarator);
Error(localDiagnostics, ErrorCode.ERR_FixedMustInit, declarator);
hasErrors = true;
}
}
else if (kind == LocalDeclarationKind.Constant && initializerOpt != null)
else if (kind == LocalDeclarationKind.Constant && initializerOpt != null && !localDiagnostics.HasAnyResolvedErrors())
{
foreach (var diagnostic in localSymbol.GetConstantValueDiagnostics(initializerOpt))
var constantValueDiagnostics = localSymbol.GetConstantValueDiagnostics(initializerOpt);
foreach (var diagnostic in constantValueDiagnostics)
{
diagnostics.Add(diagnostic);
hasErrors = true;
}
}
diagnostics.AddRangeAndFree(localDiagnostics);
var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declTypeOpt);
return new BoundLocalDeclaration(associatedSyntaxNode, localSymbol, boundDeclType, initializerOpt, arguments, hasErrors);
}
......
......@@ -1862,7 +1862,7 @@ public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
get { throw new NotImplementedException(); }
}
internal override ConstantValue GetConstantValue(LocalSymbol inProgress)
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics)
{
throw new NotImplementedException();
}
......
......@@ -127,6 +127,7 @@ internal static class ConstantValueUtils
}
}
}
return value;
}
......
......@@ -289,7 +289,7 @@ public bool HasConstantValue
return false;
}
ConstantValue constantValue = this.GetConstantValue(null);
ConstantValue constantValue = this.GetConstantValue(null, null, null);
return constantValue != null && !constantValue.IsBad; //can be null in error scenarios
}
}
......@@ -307,9 +307,8 @@ public object ConstantValue
return null;
}
ConstantValue constantValue = this.GetConstantValue(null); //null just means we aren't currently evaluating another constant
return constantValue == null ? null : constantValue.Value; //can be null in error scenarios
ConstantValue constantValue = this.GetConstantValue(null, null, null);
return constantValue?.Value; //can be null in error scenarios
}
}
......@@ -320,8 +319,8 @@ public object ConstantValue
{
get;
}
internal abstract ConstantValue GetConstantValue(LocalSymbol inProgress);
internal abstract ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics = null);
internal abstract ImmutableArray<Diagnostic> GetConstantValueDiagnostics(BoundExpression boundInitValue);
......
......@@ -152,7 +152,7 @@ internal override bool IsCompilerGenerated
get { return true; }
}
internal override ConstantValue GetConstantValue(LocalSymbol inProgress)
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics)
{
return null;
}
......
......@@ -17,7 +17,7 @@ public TypeSubstitutedLocalSymbol(LocalSymbol originalVariable, TypeSymbol type,
Debug.Assert(originalVariable != null);
Debug.Assert(type != null);
Debug.Assert(containingSymbol != null);
_originalVariable = originalVariable;
_type = type;
_containingSymbol = containingSymbol;
......@@ -88,9 +88,9 @@ internal override RefKind RefKind
get { return _originalVariable.RefKind; }
}
internal override ConstantValue GetConstantValue(LocalSymbol inProgress)
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics)
{
return _originalVariable.GetConstantValue(inProgress);
return _originalVariable.GetConstantValue(node, inProgress, diagnostics);
}
internal override ImmutableArray<Diagnostic> GetConstantValueDiagnostics(BoundExpression boundInitValue)
......
......@@ -1809,12 +1809,9 @@ void M()
Assert.Equal(SymbolKind.NamedType, symbolInfo.Symbol.Kind);
compilation.VerifyDiagnostics(
// (11,21): error CS0133: The expression being assigned to 'E' must be constant
// const E E = E.A;
Diagnostic(ErrorCode.ERR_NotConstantExpression, "E.A").WithArguments("E").WithLocation(11, 21),
// (12,13): warning CS0219: The variable 'z' is assigned but its value is never used
// var z = E;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "z").WithArguments("z").WithLocation(12, 13)
// (12,13): warning CS0219: The variable 'z' is assigned but its value is never used
// var z = E;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "z").WithArguments("z").WithLocation(12, 13)
);
}
......@@ -1872,6 +1869,9 @@ void M()
// (11,9): error CS0822: Implicitly-typed variables cannot be constant
// const var E = E.A;
Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, "const var E = E.A;").WithLocation(11, 9),
// (11,23): error CS0110: The evaluation of the constant value for 'E' involves a circular definition
// const var E = E.A;
Diagnostic(ErrorCode.ERR_CircConstValue, "E").WithArguments("E").WithLocation(11, 23),
// (11,23): error CS0841: Cannot use local variable 'E' before it is declared
// const var E = E.A;
Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "E").WithArguments("E").WithLocation(11, 23)
......
......@@ -1614,63 +1614,93 @@ void M()
}
}";
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
// (7,15): error CS0283: The type 'C.S' cannot be declared const
Diagnostic(ErrorCode.ERR_BadConstType, "S").WithArguments("C.S"),
// (8,28): error CS0023: Operator '-' cannot be applied to operand of type 'ulong'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-9223372036854775808UL").WithArguments("-", "ulong"),
// (9,28): error CS0023: Operator '-' cannot be applied to operand of type 'ulong'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-9223372036854775808ul").WithArguments("-", "ulong"),
// (12,27): error CS0133: The expression being assigned to 's2' must be constant
Diagnostic(ErrorCode.ERR_NotConstantExpression, "s1").WithArguments("s2"),
// (14,27): error CS0134: 'o1' is of type 'object'. A const field of a reference type other than string can only be initialized with null.
Diagnostic(ErrorCode.ERR_NotNullConstRefField, @"""hello""").WithArguments("o1", "object"),
// (16,18): error CS0020: Division by constant zero
Diagnostic(ErrorCode.ERR_IntDivByZero, "1 / 0"),
// (16,28): error CS0020: Division by constant zero
Diagnostic(ErrorCode.ERR_IntDivByZero, "1L/0L"),
// (16,38): error CS0020: Division by constant zero
Diagnostic(ErrorCode.ERR_IntDivByZero, "1UL/0UL"),
// (16,50): error CS0020: Division by constant zero
Diagnostic(ErrorCode.ERR_IntDivByZero, "1M/0M"),
// (16,60): error CS0463: Evaluation of the decimal constant expression failed
Diagnostic(ErrorCode.ERR_DecConstError, "-79228162514264337593543950335m - 1m"),
// (18,19): error CS0133: The expression being assigned to 'z' must be constant
Diagnostic(ErrorCode.ERR_NotConstantExpression, "1 + (z + 1)").WithArguments("z"),
// (20,29): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'int' (use 'unchecked' syntax to override)
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(int)0x8888888888888888").WithArguments("9838263505978427528", "int"),
// (21,31): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'uint' (use 'unchecked' syntax to override)
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(uint)0x8888888888888888").WithArguments("9838263505978427528", "uint"),
// (22,31): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'long' (use 'unchecked' syntax to override)
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(long)0x8888888888888888").WithArguments("9838263505978427528", "long"),
// (23,33): error CS0221: Constant value '1E+50' cannot be converted to a 'ulong' (use 'unchecked' syntax to override)
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(ulong)1E50").WithArguments("1E+50", "ulong"),
// (25,27): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "int.MaxValue + 1"),
// (26,29): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "uint.MaxValue + 1"),
// (27,29): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "long.MaxValue + 1"),
// (28,31): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "ulong.MaxValue + 1"),
// (30,28): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "int.MinValue - 1"),
// (31,30): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "uint.MinValue - 1"),
// (32,30): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "long.MinValue - 1"),
// (33,32): error CS0220: The operation overflows at compile time in checked mode
Diagnostic(ErrorCode.ERR_CheckedOverflow, "ulong.MinValue - 1"),
// (7,17): warning CS0219: The variable 's' is assigned but its value is never used
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s").WithArguments("s"),
// (20,13): warning CS0219: The variable 'intConversion' is assigned but its value is never used
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "intConversion").WithArguments("intConversion"),
// (21,14): warning CS0219: The variable 'uintConversion' is assigned but its value is never used
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "uintConversion").WithArguments("uintConversion"),
// (22,14): warning CS0219: The variable 'longConversion' is assigned but its value is never used
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "longConversion").WithArguments("longConversion"),
// (23,15): warning CS0219: The variable 'ulongConversion' is assigned but its value is never used
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "ulongConversion").WithArguments("ulongConversion"));
// (7,15): error CS0283: The type 'C.S' cannot be declared const
// const S s = new S();
Diagnostic(ErrorCode.ERR_BadConstType, "S").WithArguments("C.S").WithLocation(7, 15),
// (8,28): error CS0023: Operator '-' cannot be applied to operand of type 'ulong'
// const double ul1 = -9223372036854775808UL + 0;
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-9223372036854775808UL").WithArguments("-", "ulong").WithLocation(8, 28),
// (9,28): error CS0023: Operator '-' cannot be applied to operand of type 'ulong'
// const double ul2 = -9223372036854775808ul + 0;
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-9223372036854775808ul").WithArguments("-", "ulong").WithLocation(9, 28),
// (12,27): error CS0133: The expression being assigned to 's2' must be constant
// const string s2 = s1; // Not a constant
Diagnostic(ErrorCode.ERR_NotConstantExpression, "s1").WithArguments("s2").WithLocation(12, 27),
// (14,27): error CS0134: 'o1' is of type 'object'. A const field of a reference type other than string can only be initialized with null.
// const object o1 = "hello"; // Constants of ref type other than string must be null.
Diagnostic(ErrorCode.ERR_NotNullConstRefField, @"""hello""").WithArguments("o1", "object").WithLocation(14, 27),
// (16,60): error CS0463: Evaluation of the decimal constant expression failed
// int y = (1 / 0) + (1L/0L) + (1UL/0UL) + (1M/0M) + (-79228162514264337593543950335m - 1m);
Diagnostic(ErrorCode.ERR_DecConstError, "-79228162514264337593543950335m - 1m").WithLocation(16, 60),
// (16,50): error CS0020: Division by constant zero
// int y = (1 / 0) + (1L/0L) + (1UL/0UL) + (1M/0M) + (-79228162514264337593543950335m - 1m);
Diagnostic(ErrorCode.ERR_IntDivByZero, "1M/0M").WithLocation(16, 50),
// (16,38): error CS0020: Division by constant zero
// int y = (1 / 0) + (1L/0L) + (1UL/0UL) + (1M/0M) + (-79228162514264337593543950335m - 1m);
Diagnostic(ErrorCode.ERR_IntDivByZero, "1UL/0UL").WithLocation(16, 38),
// (16,28): error CS0020: Division by constant zero
// int y = (1 / 0) + (1L/0L) + (1UL/0UL) + (1M/0M) + (-79228162514264337593543950335m - 1m);
Diagnostic(ErrorCode.ERR_IntDivByZero, "1L/0L").WithLocation(16, 28),
// (16,18): error CS0020: Division by constant zero
// int y = (1 / 0) + (1L/0L) + (1UL/0UL) + (1M/0M) + (-79228162514264337593543950335m - 1m);
Diagnostic(ErrorCode.ERR_IntDivByZero, "1 / 0").WithLocation(16, 18),
// (18,28): error CS0110: The evaluation of the constant value for 'z' involves a circular definition
// const int z = 1 + (z + 1);
Diagnostic(ErrorCode.ERR_CircConstValue, "z").WithArguments("z").WithLocation(18, 28),
// (20,29): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'int' (use 'unchecked' syntax to override)
// int intConversion = (int)0x8888888888888888;
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(int)0x8888888888888888").WithArguments("9838263505978427528", "int").WithLocation(20, 29),
// (21,31): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'uint' (use 'unchecked' syntax to override)
// uint uintConversion = (uint)0x8888888888888888;
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(uint)0x8888888888888888").WithArguments("9838263505978427528", "uint").WithLocation(21, 31),
// (22,31): error CS0221: Constant value '9838263505978427528' cannot be converted to a 'long' (use 'unchecked' syntax to override)
// long longConversion = (long)0x8888888888888888;
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(long)0x8888888888888888").WithArguments("9838263505978427528", "long").WithLocation(22, 31),
// (23,33): error CS0221: Constant value '1E+50' cannot be converted to a 'ulong' (use 'unchecked' syntax to override)
// ulong ulongConversion = (ulong)1E50;
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(ulong)1E50").WithArguments("1E+50", "ulong").WithLocation(23, 33),
// (25,27): error CS0220: The operation overflows at compile time in checked mode
// int intOverflow = int.MaxValue + 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "int.MaxValue + 1").WithLocation(25, 27),
// (26,29): error CS0220: The operation overflows at compile time in checked mode
// uint uintOverflow = uint.MaxValue + 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "uint.MaxValue + 1").WithLocation(26, 29),
// (27,29): error CS0220: The operation overflows at compile time in checked mode
// long longOverflow = long.MaxValue + 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "long.MaxValue + 1").WithLocation(27, 29),
// (28,31): error CS0220: The operation overflows at compile time in checked mode
// ulong ulongOverflow = ulong.MaxValue + 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "ulong.MaxValue + 1").WithLocation(28, 31),
// (30,28): error CS0220: The operation overflows at compile time in checked mode
// int intUnderflow = int.MinValue - 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "int.MinValue - 1").WithLocation(30, 28),
// (31,30): error CS0220: The operation overflows at compile time in checked mode
// uint uintUnderflow = uint.MinValue - 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "uint.MinValue - 1").WithLocation(31, 30),
// (32,30): error CS0220: The operation overflows at compile time in checked mode
// long longUnderflow = long.MinValue - 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "long.MinValue - 1").WithLocation(32, 30),
// (33,32): error CS0220: The operation overflows at compile time in checked mode
// ulong ulongUnderflow = ulong.MinValue - 1;
Diagnostic(ErrorCode.ERR_CheckedOverflow, "ulong.MinValue - 1").WithLocation(33, 32),
// (7,17): warning CS0219: The variable 's' is assigned but its value is never used
// const S s = new S();
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s").WithArguments("s").WithLocation(7, 17),
// (20,13): warning CS0219: The variable 'intConversion' is assigned but its value is never used
// int intConversion = (int)0x8888888888888888;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "intConversion").WithArguments("intConversion").WithLocation(20, 13),
// (21,14): warning CS0219: The variable 'uintConversion' is assigned but its value is never used
// uint uintConversion = (uint)0x8888888888888888;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "uintConversion").WithArguments("uintConversion").WithLocation(21, 14),
// (22,14): warning CS0219: The variable 'longConversion' is assigned but its value is never used
// long longConversion = (long)0x8888888888888888;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "longConversion").WithArguments("longConversion").WithLocation(22, 14),
// (23,15): warning CS0219: The variable 'ulongConversion' is assigned but its value is never used
// ulong ulongConversion = (ulong)1E50;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "ulongConversion").WithArguments("ulongConversion").WithLocation(23, 15)
);
}
[Fact]
public void TestDynamicConstantError()
{
......@@ -1730,17 +1760,17 @@ class C
{
void M()
{
const int crem = checked(int.MinValue % (-1));
const int urem = unchecked(int.MinValue % (-1));
const int crem = checked(int.MinValue % (-1));
const int urem = unchecked(int.MinValue % (-1));
const long creml = checked(long.MinValue % (-1));
const long ureml = unchecked(long.MinValue % (-1));
const long creml = checked(long.MinValue % (-1));
const long ureml = unchecked(long.MinValue % (-1));
const int cdiv = checked(int.MinValue / (-1));
const int udiv = unchecked(int.MinValue / (-1));
const int udiv = unchecked(int.MinValue / (-1));
const long cdivl = checked(long.MinValue / (-1));
const long udivl = unchecked(long.MinValue / (-1));
const long udivl = unchecked(long.MinValue / (-1));
System.Console.WriteLine(null, crem, urem, creml, ureml, cdiv, udiv, cdivl, udivl);
}
......@@ -2755,6 +2785,43 @@ static void Main(string[] args)
);
}
[Fact]
public static void DoubleRecursiveConst()
{
var source =
@"using System;
class C
{
public static void Main()
{
const Func<int> a = () => { const int b = a(); return 1; };
}
}";
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
// (6,51): error CS0133: The expression being assigned to 'b' must be constant
// const Func<int> a = () => { const int b = a(); return 1; };
Diagnostic(ErrorCode.ERR_NotConstantExpression, "a()").WithArguments("b").WithLocation(6, 51)
);
}
[Fact]
public static void RecursiveConst()
{
var source =
@"class C
{
public static void Main()
{
const int z = 1 + z + 1;
}
}";
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
// (5,27): error CS0110: The evaluation of the constant value for 'z' involves a circular definition
// const int z = 1 + z + 1;
Diagnostic(ErrorCode.ERR_CircConstValue, "z").WithArguments("z").WithLocation(5, 27)
);
}
[Fact, WorkItem(1098197, "DevDiv")]
public static void Bug1098197_02()
{
......
......@@ -3581,17 +3581,21 @@ static void M()
[Fact]
public void CS0133ERR_NotConstantExpression04()
{
DiagnosticsUtils.TestDiagnosticsExact(
var source =
@"class C
{
static void M()
{
const int x = x + x;
}
}
",
//"'x + x' error CS0133: The expression being assigned to 'x' must be constant",
"'x + x' error CS0133: The expression being assigned to 'x' must be constant");
}";
CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
// (5,27): error CS0110: The evaluation of the constant value for 'x' involves a circular definition
// const int x = x + x;
Diagnostic(ErrorCode.ERR_CircConstValue, "x").WithArguments("x").WithLocation(5, 27),
// (5,23): error CS0110: The evaluation of the constant value for 'x' involves a circular definition
// const int x = x + x;
Diagnostic(ErrorCode.ERR_CircConstValue, "x").WithArguments("x").WithLocation(5, 23));
}
[Fact]
......
......@@ -76,6 +76,33 @@ public bool HasAnyErrors()
return false;
}
/// <summary>
/// Returns true if the bag has any non-lazy diagnostics with Severity=Error.
/// </summary>
/// <remarks>
/// Does not resolve any lazy diagnostics in the bag.
///
/// Generally, this should only be called by the creator (modulo pooling) of the bag (i.e. don't use bags to communicate -
/// if you need more info, pass more info).
/// </remarks>
internal bool HasAnyResolvedErrors()
{
if (IsEmptyWithoutResolution)
{
return false;
}
foreach (Diagnostic diagnostic in Bag)
{
if ((diagnostic as DiagnosticWithInfo)?.HasLazyInfo != true && diagnostic.Severity == DiagnosticSeverity.Error)
{
return true;
}
}
return false;
}
/// <summary>
/// Add a diagnostic to the bag.
/// </summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册