2008-02-14 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Thu, 14 Feb 2008 23:24:14 +0000 (23:24 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Thu, 14 Feb 2008 23:24:14 +0000 (23:24 -0000)
* expression.cs: Do not fold BitwiseAnd operators when the left
side is a false constant, because we still need to evaluate the
right-hand side.

Fixes #359789

svn path=/trunk/mcs/; revision=95709

mcs/mcs/ChangeLog
mcs/mcs/expression.cs
mcs/tests/test-613.cs [new file with mode: 0644]

index 55080257d0fb4709e500aa5d5c89d8b1f91cf671..61dc49bde1e5d455fdb60589af9065d7ec9d31d0 100644 (file)
@@ -1,6 +1,15 @@
 2008-02-14  Miguel de Icaza  <miguel@novell.com>
 
-       * support.cs: Increase the size.
+       * expression.cs: Do not fold BitwiseAnd operators when the left
+       side is a false constant, because we still need to evaluate the
+       right-hand side. 
+
+       Fixes #359789
+
+       * support.cs: Instead of throwing an InternalErrorException when
+       the position of the stream is outside the boundary of our buffer,
+       reset the state of the reader, and restart the reading from the
+       beginning of the file.
 
 2008-02-14  Marek Safar  <marek.safar@gmail.com>
 
index 459cb34c6d4c2f61df6e396d7e3cfa743a990fcf..de441a698009331244af65f43ef78c81bcfefd8e 100644 (file)
@@ -2473,40 +2473,40 @@ namespace Mono.CSharp {
                Constant EnumLiftUp (Constant left, Constant right)
                {
                        switch (oper) {
-                               case Operator.BitwiseOr:
-                               case Operator.BitwiseAnd:
-                               case Operator.ExclusiveOr:
-                               case Operator.Equality:
-                               case Operator.Inequality:
-                               case Operator.LessThan:
-                               case Operator.LessThanOrEqual:
-                               case Operator.GreaterThan:
-                               case Operator.GreaterThanOrEqual:
-                                       if (left is EnumConstant)
-                                               return left;
-
-                                       if (left.IsZeroInteger)
-                                               return new EnumConstant (left, right.Type);
-
-                                       break;
-
-                               case Operator.Addition:
-                               case Operator.Subtraction:
-                                       return left;
-
-                               case Operator.Multiply:
-                               case Operator.Division:
-                               case Operator.Modulus:
-                               case Operator.LeftShift:
-                               case Operator.RightShift:
-                                       if (right is EnumConstant || left is EnumConstant)
-                                               break;
+                       case Operator.BitwiseOr:
+                       case Operator.BitwiseAnd:
+                       case Operator.ExclusiveOr:
+                       case Operator.Equality:
+                       case Operator.Inequality:
+                       case Operator.LessThan:
+                       case Operator.LessThanOrEqual:
+                       case Operator.GreaterThan:
+                       case Operator.GreaterThanOrEqual:
+                               if (left is EnumConstant)
                                        return left;
+                               
+                               if (left.IsZeroInteger)
+                                       return new EnumConstant (left, right.Type);
+                               
+                               break;
+                               
+                       case Operator.Addition:
+                       case Operator.Subtraction:
+                               return left;
+                               
+                       case Operator.Multiply:
+                       case Operator.Division:
+                       case Operator.Modulus:
+                       case Operator.LeftShift:
+                       case Operator.RightShift:
+                               if (right is EnumConstant || left is EnumConstant)
+                                       break;
+                               return left;
                        }
                        Error_OperatorCannotBeApplied ();
                        return null;
                }
-
+               
                public override Expression DoResolve (EmitContext ec)
                {
                        if (left == null)
@@ -2564,9 +2564,10 @@ namespace Mono.CSharp {
                                }
 
                                if (lc != null && lc.IsZeroInteger) {
-                                       return rc is EnumConstant ?
-                                               new EnumConstant (lc, rc.Type):
-                                               lc;
+                                       if (rc is EnumConstant)
+                                               return new EnumConstant (lc, rc.Type);
+                                       Type = TypeManager.bool_type;
+                                       return this;
                                }
                        }
                        else if (oper == Operator.BitwiseOr) {
diff --git a/mcs/tests/test-613.cs b/mcs/tests/test-613.cs
new file mode 100644 (file)
index 0000000..1ddf19c
--- /dev/null
@@ -0,0 +1,25 @@
+//
+// Checks that we do not short-circuit the bitwise and operation
+// See bug: 359789
+//
+public class M {
+       static bool called;
+       
+       public static bool g() {
+               called = true;
+               return false;
+       }
+
+       public static int Main() {
+               called = false;
+               System.Console.WriteLine (false & g());
+               if (!called)
+                       return 1;
+
+               called = false;
+               System.Console.WriteLine (true | g());
+               if (!called)
+                       return 1;
+               return 0;
+       }
+}