Initial set of Ward sgen annotations (#5705)
[mono.git] / mcs / mcs / cfold.cs
index 72f3a9c3620eb72e7c9a3e6c11afda7fd69c922d..f19c1a400e33d6e0f676f93f4cdf15f3af415129 100644 (file)
@@ -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;
@@ -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) {
@@ -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){