Skip to content

Commit

Permalink
Reject out of range constant conversion to nullable enum.
Browse files Browse the repository at this point in the history
  • Loading branch information
marek-safar committed Sep 14, 2012
1 parent e350075 commit 7bd0ccd
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 25 deletions.
12 changes: 12 additions & 0 deletions mcs/errors/cs0030-15.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// CS0030: Cannot convert type `long' to `System.DayOfWeek?'
// Line: 10

using System;

class C
{
static void Main ()
{
var dow = (DayOfWeek?) long.MaxValue;
}
}
8 changes: 4 additions & 4 deletions mcs/mcs/cfold.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
case Binary.Operator.ExclusiveOr:
result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
if (result != null)
result = result.TryReduce (ec, lt);
result = result.Reduce (ec, lt);
return result;

///
Expand All @@ -158,7 +158,7 @@ static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
case Binary.Operator.Subtraction:
result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
if (result != null)
result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt));
result = result.Reduce (ec, EnumSpec.GetUnderlyingType (lt));
return result;

///
Expand Down Expand Up @@ -340,7 +340,7 @@ static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
if (result == null)
return null;

result = result.TryReduce (ec, lt);
result = result.Reduce (ec, lt);
if (result == null)
return null;

Expand Down Expand Up @@ -459,7 +459,7 @@ static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
if (result == null)
return null;

result = result.TryReduce (ec, lt);
result = result.Reduce (ec, lt);
if (result == null)
return null;

Expand Down
19 changes: 15 additions & 4 deletions mcs/mcs/constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,12 @@ protected override Expression DoResolve (ResolveContext rc)
return this;
}

/// <summary>
/// Attempts to do a compile-time folding of a constant cast.
/// </summary>
public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
//
// Attempts to do a compile-time folding of a constant cast and handles
// error reporting for constant overlows only, on normal conversion
// errors returns null
//
public Constant Reduce (ResolveContext ec, TypeSpec target_type)
{
try {
return TryReduceConstant (ec, target_type);
Expand All @@ -271,6 +273,15 @@ public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
}
}

public Constant TryReduce (ResolveContext rc, TypeSpec targetType)
{
try {
return TryReduceConstant (rc, targetType);
} catch (OverflowException) {
return null;
}
}

Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
{
if (Type == target_type) {
Expand Down
35 changes: 21 additions & 14 deletions mcs/mcs/convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ static Expression UserDefinedConversion (ResolveContext ec, Expression source, T
if (s_x != source_type) {
var c = source as Constant;
if (c != null) {
source = c.TryReduce (ec, s_x);
source = c.Reduce (ec, s_x);
if (source == null)
c = null;
}
Expand Down Expand Up @@ -1990,21 +1990,28 @@ static public Expression ExplicitConversionCore (ResolveContext ec, Expression e
if (expr_type == real_target)
return EmptyCast.Create (expr, target_type);

ne = ImplicitNumericConversion (expr, real_target);
if (ne != null)
return EmptyCast.Create (ne, target_type);

ne = ExplicitNumericConversion (ec, expr, real_target);
if (ne != null)
return EmptyCast.Create (ne, target_type);
Constant c = expr as Constant;
if (c != null) {
c = c.TryReduce (ec, real_target);
if (c != null)
return c;
} else {
ne = ImplicitNumericConversion (expr, real_target);
if (ne != null)
return EmptyCast.Create (ne, target_type);

//
// LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
//
if (expr_type.BuiltinType == BuiltinTypeSpec.Type.IntPtr || expr_type.BuiltinType == BuiltinTypeSpec.Type.UIntPtr) {
ne = ExplicitUserConversion (ec, expr, real_target, loc);
ne = ExplicitNumericConversion (ec, expr, real_target);
if (ne != null)
return ExplicitConversionCore (ec, ne, target_type, loc);
return EmptyCast.Create (ne, target_type);

//
// LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
//
if (expr_type.BuiltinType == BuiltinTypeSpec.Type.IntPtr || expr_type.BuiltinType == BuiltinTypeSpec.Type.UIntPtr) {
ne = ExplicitUserConversion (ec, expr, real_target, loc);
if (ne != null)
return ExplicitConversionCore (ec, ne, target_type, loc);
}
}
} else {
ne = ExplicitNumericConversion (ec, expr, target_type);
Expand Down
4 changes: 2 additions & 2 deletions mcs/mcs/expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,7 +1702,7 @@ protected override Expression DoResolve (ResolveContext ec)

Constant c = expr as Constant;
if (c != null) {
c = c.TryReduce (ec, type);
c = c.Reduce (ec, type);
if (c != null)
return c;
}
Expand Down Expand Up @@ -2661,7 +2661,7 @@ Constant EnumLiftUp (ResolveContext ec, Constant left, Constant right, Location
return left;

if (left.IsZeroInteger)
return left.TryReduce (ec, right.Type);
return left.Reduce (ec, right.Type);

break;

Expand Down
2 changes: 1 addition & 1 deletion mcs/mcs/statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ public override bool Resolve (BlockContext ec)
res = c;
} else {
TypeSpec type = ec.Switch.SwitchType;
res = c.TryReduce (ec, type);
res = c.Reduce (ec, type);
if (res == null) {
c.Error_ValueCannotBeConverted (ec, type, true);
return false;
Expand Down

0 comments on commit 7bd0ccd

Please sign in to comment.