X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcfold.cs;h=f19c1a400e33d6e0f676f93f4cdf15f3af415129;hb=e3685c4c9aad38851097cff877dc0fb7ed47ab10;hp=96062f2748e744c51360f607ad2de8f492dc889d;hpb=b86af4848657c5fa6041d0eefa47ac004dc54442;p=mono.git diff --git a/mcs/mcs/cfold.cs b/mcs/mcs/cfold.cs index 96062f2748e..f19c1a400e3 100644 --- a/mcs/mcs/cfold.cs +++ b/mcs/mcs/cfold.cs @@ -309,10 +309,10 @@ namespace Mono.CSharp { return new StringConstant (ec.BuiltinTypes, (string)left.GetValue () + (string)right.GetValue (), left.Location); - if (lt == InternalType.NullLiteral) + if (lt == InternalType.NullLiteral || left.IsNull) return new StringConstant (ec.BuiltinTypes, "" + right.GetValue (), left.Location); - if (rt == InternalType.NullLiteral) + if (rt == InternalType.NullLiteral || right.IsNull) return new StringConstant (ec.BuiltinTypes, left.GetValue () + "", left.Location); return null; @@ -367,8 +367,8 @@ namespace Mono.CSharp { return null; result = result.Reduce (ec, lt); - if (result == null) - return null; + if (result == null || lt.IsEnum) + return result; return new EnumConstant (result, lt); } @@ -390,14 +390,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value + - ((FloatConstant) right).Value); + res = checked (a + b); else - res = unchecked (((FloatConstant) left).Value + - ((FloatConstant) right).Value); + res = unchecked (a + b); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -469,27 +469,37 @@ namespace Mono.CSharp { // lc = left as EnumConstant; rc = right as EnumConstant; - if (lc != null || rc != null){ + if (lc != null || rc != null) { + TypeSpec res_type; if (lc == null) { - lc = rc; - lt = lc.Type; - right = left; - } + res_type = right.Type; - // U has to be implicitly convetible to E.base - right = right.ConvertImplicitly (lc.Child.Type); - if (right == null) - return null; + // Y has to be implicitly convertible to E.base + left = left.ConvertImplicitly (rc.Child.Type); + if (left == null) + return null; - result = BinaryFold (ec, oper, lc.Child, right, loc); + right = rc.Child; + } else { + res_type = left.Type; + + // U has to be implicitly convertible to E.base + right = right.ConvertImplicitly (lc.Child.Type); + if (right == null) + return null; + + left = lc.Child; + } + + result = BinaryFold (ec, oper, left, right, loc); if (result == null) return null; - result = result.Reduce (ec, lt); + result = result.Reduce (ec, res_type); if (result == null) return null; - return new EnumConstant (result, lt); + return new EnumConstant (result, res_type); } if (left is NullLiteral && right is NullLiteral) { @@ -514,14 +524,14 @@ namespace Mono.CSharp { result = new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value - - ((FloatConstant) right).Value); + res = checked (a - b); else - res = unchecked (((FloatConstant) left).Value - - ((FloatConstant) right).Value); + res = unchecked (a - b); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -611,14 +621,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + res = checked (a * b); else - res = unchecked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + res = unchecked (a * b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -707,14 +717,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + res = checked (a / b); else - res = unchecked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + res = unchecked (a / b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -807,14 +817,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value % - ((FloatConstant) right).Value); + res = checked (a % b); else - res = unchecked (((FloatConstant) left).Value % - ((FloatConstant) right).Value); + res = unchecked (a % b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -861,9 +871,22 @@ namespace Mono.CSharp { ((IntConstant) right).Value); return new IntConstant (ec.BuiltinTypes, res, left.Location); - } else { - throw new Exception ( "Unexepected modulus input: " + left); } + + if (left is DecimalConstant) { + decimal res; + + if (ec.ConstantCheckState) + res = checked (((DecimalConstant) left).Value % + ((DecimalConstant) right).Value); + else + res = unchecked (((DecimalConstant) left).Value % + ((DecimalConstant) right).Value); + + return new DecimalConstant (ec.BuiltinTypes, res, left.Location); + } + + throw new Exception ( "Unexepected modulus input: " + left); } catch (DivideByZeroException){ ec.Report.Error (20, loc, "Division by constant zero"); } catch (OverflowException){ @@ -883,7 +906,6 @@ namespace Mono.CSharp { IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (ic == null){ - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); return null; } @@ -905,8 +927,7 @@ namespace Mono.CSharp { if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value << lshift_val, left.Location); - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); - break; + return null; // // There is no overflow checking on right shift @@ -920,7 +941,6 @@ namespace Mono.CSharp { IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (sic == null){ - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); return null; } int rshift_val = sic.Value; @@ -941,8 +961,7 @@ namespace Mono.CSharp { if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value >> rshift_val, left.Location); - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); - break; + return null; case Binary.Operator.Equality: if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) || @@ -969,8 +988,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value == ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value == - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue == + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value == ((ULongConstant) right).Value; @@ -1013,8 +1032,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value != ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value != - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue != + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value != ((ULongConstant) right).Value; @@ -1049,8 +1068,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value < ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value < - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue < + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value < ((ULongConstant) right).Value; @@ -1085,8 +1104,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value > ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value > - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue > + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value > ((ULongConstant) right).Value; @@ -1121,8 +1140,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value >= ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value >= - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue >= + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value >= ((ULongConstant) right).Value; @@ -1157,8 +1176,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value <= ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value <= - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue <= + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value <= ((ULongConstant) right).Value; @@ -1176,7 +1195,7 @@ namespace Mono.CSharp { return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); } - + return null; } }