* XmlTypeAttribute.cs: added property AnonymousType for 2.0
[mono.git] / mcs / mcs / cfold.cs
index 9e8a5a1a6293a1de740c20cb86e3fc3ef0ebbc6d..aba3ad37c485097ae96c089ed69eba1aa676322f 100644 (file)
@@ -174,6 +174,12 @@ namespace Mono.CSharp {
                static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
                                                     Constant left, Constant right, Location loc)
                {
+                       if (left is NullCast)
+                               return BinaryFold (ec, oper, ((NullCast)left).child, right, loc);
+
+                       if (right is NullCast)
+                               return BinaryFold (ec, oper, left, ((NullCast)right).child, loc);
+
                        Type lt = left.Type;
                        Type rt = right.Type;
                        Type result_type = null;
@@ -196,6 +202,23 @@ namespace Mono.CSharp {
                                        right = ((EnumConstant) right).Child;
                        }
 
+                       if (left is BoolConstant && right is BoolConstant) {
+                               bool lv = ((BoolConstant) left ).Value;
+                               bool rv = ((BoolConstant) right).Value;
+                               switch (oper) {
+                               case Binary.Operator.BitwiseAnd:
+                               case Binary.Operator.LogicalAnd:
+                                       return new BoolConstant (lv && rv, left.Location);
+                               case Binary.Operator.BitwiseOr:
+                               case Binary.Operator.LogicalOr:
+                                       return new BoolConstant (lv || rv, left.Location);
+                               case Binary.Operator.ExclusiveOr:
+                                       return new BoolConstant (lv ^ rv, left.Location);
+                               default:
+                                       throw new InternalErrorException ("Invalid operator on booleans: " + oper);
+                               }
+                       }
+
                        Type wrap_as;
                        Constant result = null;
                        switch (oper){
@@ -527,8 +550,14 @@ namespace Mono.CSharp {
                                        Error_CompileTimeOverflow (loc);
                                }
 
-                               if (wrap_as != null)
-                                       return result.TryReduce (ec, wrap_as, loc);
+                               if (wrap_as != null) {
+                                       try {
+                                               return result.TryReduce (ec, wrap_as, loc);
+                                       }
+                                       catch (OverflowException) {
+                                               return null;
+                                       }
+                               }
                                else
                                        return result;
 
@@ -659,8 +688,14 @@ namespace Mono.CSharp {
                                        Error_CompileTimeOverflow (loc);
                                }
 
-                               if (wrap_as != null)
-                                       return result.TryReduce (ec, wrap_as, loc);
+                               if (wrap_as != null) {
+                                       try {
+                                               return result.TryReduce (ec, wrap_as, loc);
+                                       }
+                                       catch (OverflowException) {
+                                               return null;
+                                       }
+                               }
 
                                return result;
                                
@@ -992,22 +1027,6 @@ namespace Mono.CSharp {
                                Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
                                break;
 
-                       case Binary.Operator.LogicalAnd:
-                               if (left is BoolConstant && right is BoolConstant){
-                                       return new BoolConstant (
-                                               ((BoolConstant) left).Value &&
-                                               ((BoolConstant) right).Value, left.Location);
-                               }
-                               break;
-
-                       case Binary.Operator.LogicalOr:
-                               if (left is BoolConstant && right is BoolConstant){
-                                       return new BoolConstant (
-                                               ((BoolConstant) left).Value ||
-                                               ((BoolConstant) right).Value, left.Location);
-                               }
-                               break;
-                               
                        case Binary.Operator.Equality:
                                if (left is BoolConstant && right is BoolConstant){
                                        return new BoolConstant (