[mono/mono] b055fa22: Fixes too early optimization of binary &&/& bool constants. Fixes part of #15392

"Marek Safar ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000141c2488a61-88e7edd3-8e70-4dda-9082-fb3cfc9d1c12-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/346b2ee26065...b055fa22dfaf

   Commit: b055fa22dfaf8feb28c0ba4db9e5fb7c90b420b1
   Author: Marek Safar <[email protected]> (marek-safar)
     Date: 2013-10-16 17:17:25 GMT
      URL: https://github.com/mono/mono/commit/b055fa22dfaf8feb28c0ba4db9e5fb7c90b420b1

Fixes too early optimization of binary &&/& bool constants. Fixes part of #15392

Changed paths:
  M mcs/errors/known-issues-net_4_5
  M mcs/mcs/ecore.cs
  M mcs/mcs/expression.cs
  M mcs/tests/ver-il-net_4_5.xml
Added paths:
  A mcs/errors/cs0165-21.cs
  A mcs/errors/cs0429-3.cs
  A mcs/tests/test-871.cs

Added: mcs/errors/cs0165-21.cs
===================================================================
@@ -0,0 +1,19 @@
+// CS0165: Use of unassigned local variable `v'
+// Line: 17
+
+using System;
+
+class C
+{
+	void Test (int arg)
+	{
+		int v;
+		switch (arg) {
+			case 1:
+				v = 0;
+				break;
+		}
+
+		Console.WriteLine (v);
+	}
+}
\ No newline at end of file

Added: mcs/errors/cs0429-3.cs
===================================================================
@@ -0,0 +1,11 @@
+// CS0429: Unreachable expression code detected
+// Line: 9
+// Compiler options: -warn:4 -warnaserror
+
+class Main
+{
+	public void Method (int i)
+	{
+		var x = true ? 1 : i;
+	}
+}

Modified: mcs/errors/known-issues-net_4_5
===================================================================
@@ -15,6 +15,7 @@
 cs0080.cs 
 
 cs0162-7.cs NO ERROR
+cs0165-3.cs
 
 # Operators
 cs0457-2.cs

Modified: mcs/mcs/ecore.cs
===================================================================
@@ -373,6 +373,11 @@ protected void Error_VoidPointerOperation (ResolveContext rc)
 			rc.Report.Error (242, loc, "The operation in question is undefined on void pointers");
 		}
 
+		public static void Warning_UnreachableExpression (ResolveContext rc, Location loc)
+		{
+			rc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+		}
+
 		public ResolveFlags ExprClassToResolveFlags {
 			get {
 				switch (eclass) {

Modified: mcs/mcs/expression.cs
===================================================================
@@ -2010,11 +2010,17 @@ public virtual Expression ConvertResult (ResolveContext rc, Binary b)
 							b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location);
 							return ReducedExpression.Create (b.left, b).Resolve (rc);
 						}
-					} else {
+
 						//
-						// Optimizes
+						// Optimizes (value &/&& 0) to 0
+						//
+						if ((b.oper == Operator.BitwiseAnd || b.oper == Operator.LogicalAnd) && !IsLifted) {
+							Constant side_effect = new SideEffectConstant (c, b.left, c.Location);
+							return ReducedExpression.Create (side_effect, b);
+						}
+					} else {
 						//
-						// (bool? & true) to bool?
+						// Optimizes (bool? & true) to bool?
 						//
 						if (IsLifted && left_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && b.oper == Operator.BitwiseAnd) {
 							return ReducedExpression.Create (b.left, b).Resolve (rc);
@@ -2043,15 +2049,39 @@ public virtual Expression ConvertResult (ResolveContext rc, Binary b)
 							b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location);
 							return ReducedExpression.Create (b.right, b).Resolve (rc);
 						}
-					} else {
+
 						//
-						// Optimizes
+						// Optimizes (false && expr) to false
+						//
+						if (b.oper == Operator.LogicalAnd && c.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) {
+							// No rhs side-effects
+							Expression.Warning_UnreachableExpression (rc, b.right.StartLocation);
+							return ReducedExpression.Create (c, b);
+						}
+
+						//
+						// Optimizes (0 & value) to 0
+						//
+						if (b.oper == Operator.BitwiseAnd && !IsLifted) {
+							Constant side_effect = new SideEffectConstant (c, b.right, c.Location);
+							return ReducedExpression.Create (side_effect, b);
+						}
+					} else {
 						//
-						// (true & bool?) to bool?
+						// Optimizes (true & bool?) to bool?
 						//
 						if (IsLifted && left_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && b.oper == Operator.BitwiseAnd) {
 							return ReducedExpression.Create (b.right, b).Resolve (rc);
 						}
+
+						//
+						// Optimizes (true || expr) to true
+						//
+						if (b.oper == Operator.LogicalOr && c.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) {
+							// No rhs side-effects
+							Expression.Warning_UnreachableExpression (rc, b.right.StartLocation);
+							return ReducedExpression.Create (c, b);
+						}
 					}
 
 					if (b.oper == Operator.Multiply && c.IsOneInteger)
@@ -3233,23 +3263,11 @@ protected override Expression DoResolve (ResolveContext ec)
 			if (left == null)
 				return null;
 
-			Constant lc = left as Constant;
-
-			if (lc != null && lc.Type.BuiltinType == BuiltinTypeSpec.Type.Bool &&
-				((oper == Operator.LogicalAnd && lc.IsDefaultValue) ||
-				 (oper == Operator.LogicalOr && !lc.IsDefaultValue))) {
-
-				// FIXME: resolve right expression as unreachable
-				// right.Resolve (ec);
-
-				ec.Report.Warning (429, 4, right.StartLocation, "Unreachable expression code detected");
-				return left;
-			}
-
 			right = right.Resolve (ec);
 			if (right == null)
 				return null;
 
+			Constant lc = left as Constant;
 			Constant rc = right as Constant;
 
 			// The conversion rules are ignored in enum context but why
@@ -4029,17 +4047,11 @@ Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] o
 			if (best_operator == null)
 				return null;
 
-			var expr = best_operator.ConvertResult (ec, this);
-
-			if ((oper == Operator.BitwiseAnd || oper == Operator.LogicalAnd) && !best_operator.IsLifted) {
-				expr = OptimizeAndOperation (expr);
-			}
-
-			return expr;
+			return best_operator.ConvertResult (ec, this);
 		}
 
 		//
-		// Optimize &/&& constant expressions with 0 value
+		// Optimize & constant expressions with 0 value
 		//
 		Expression OptimizeAndOperation (Expression expr)
 		{
@@ -5342,8 +5354,8 @@ protected override Expression DoResolve (ResolveContext ec)
 				// Don't issue the warning for constant expressions
 				//
 				if (!(is_false ? true_expr is Constant : false_expr is Constant)) {
-					ec.Report.Warning (429, 4, is_false ? true_expr.Location : false_expr.Location,
-						"Unreachable expression code detected");
+					// CSC: Missing warning
+					Warning_UnreachableExpression (ec, is_false ? true_expr.Location : false_expr.Location);
 				}
 
 				return ReducedExpression.Create (

Added: mcs/tests/test-871.cs
===================================================================
@@ -0,0 +1,42 @@
+using System;
+
+class D
+{
+	int arg;
+
+	public D (int arg)
+	{
+		this.arg = arg;
+	}
+
+	public static D operator & (D x, D y)
+	{
+		return new D (100);
+	}
+
+	public static bool operator false (D d)
+	{
+		return false;
+	}
+
+	public static bool operator true (D d)
+	{
+		return true;
+	}
+
+	public static implicit operator D(bool b)
+	{
+		return new D (5);
+	}
+
+	static int Main ()
+	{
+		D d = false && new D (1);
+		Console.WriteLine (d.arg);
+		if (d.arg != 100)
+			return 1;
+
+		Console.WriteLine ("ok");
+		return 0;
+	}
+}
\ No newline at end of file

Modified: mcs/tests/ver-il-net_4_5.xml
===================================================================
@@ -48214,6 +48214,28 @@
       </method>
     </type>
   </test>
+  <test name="test-871.cs">
+    <type name="D">
+      <method name="D op_BitwiseAnd(D, D)" attrs="2198">
+        <size>16</size>
+      </method>
+      <method name="Boolean op_False(D)" attrs="2198">
+        <size>10</size>
+      </method>
+      <method name="Boolean op_True(D)" attrs="2198">
+        <size>10</size>
+      </method>
+      <method name="D op_Implicit(Boolean)" attrs="2198">
+        <size>15</size>
+      </method>
+      <method name="Int32 Main()" attrs="145">
+        <size>80</size>
+      </method>
+      <method name="Void .ctor(Int32)" attrs="6278">
+        <size>15</size>
+      </method>
+    </type>
+  </test>
   <test name="test-88.cs">
     <type name="X">
       <method name="Void f(System.String)" attrs="145">



_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.