[mcs] Reduced statement expressions can still be used as statements. Fixes #33142
authorMarek Safar <marek.safar@gmail.com>
Mon, 17 Aug 2015 09:42:43 +0000 (11:42 +0200)
committerMarek Safar <marek.safar@gmail.com>
Mon, 17 Aug 2015 09:43:47 +0000 (11:43 +0200)
mcs/mcs/ecore.cs
mcs/mcs/lambda.cs
mcs/tests/gtest-633.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index 68e0551bb04fa6d0d620e4421914eed02ffed2d2..ce055dcbc3139d9fc071da68dd444b936968d027 100644 (file)
@@ -1338,8 +1338,14 @@ namespace Mono.CSharp {
                                return null;
 
                        ExpressionStatement es = e as ExpressionStatement;
-                       if (es == null || e is AnonymousMethodBody)
+                       if (es == null || e is AnonymousMethodBody) {
+                               var reduced = e as IReducedExpressionStatement;
+                               if (reduced != null) {
+                                       return EmptyExpressionStatement.Instance;
+                               }
+
                                Error_InvalidExpressionStatement (ec);
+                       }
 
                        //
                        // This is quite expensive warning, try to limit the damage
@@ -1406,6 +1412,10 @@ namespace Mono.CSharp {
                }
        }
 
+       interface IReducedExpressionStatement
+       {
+       }
+
        /// <summary>
        ///   This kind of cast is used to encapsulate the child
        ///   whose type is child.Type into an expression that is
@@ -2213,7 +2223,7 @@ namespace Mono.CSharp {
        //
        public class ReducedExpression : Expression
        {
-               public sealed class ReducedConstantExpression : EmptyConstantCast
+               public class ReducedConstantExpression : EmptyConstantCast
                {
                        readonly Expression orig_expr;
 
@@ -2263,6 +2273,14 @@ namespace Mono.CSharp {
                        }
                }
 
+               sealed class ReducedConstantStatement : ReducedConstantExpression, IReducedExpressionStatement
+               {
+                       public ReducedConstantStatement (Constant expr, Expression origExpr)
+                               : base (expr, origExpr)
+                       {
+                       }
+               }
+
                sealed class ReducedExpressionStatement : ExpressionStatement
                {
                        readonly Expression orig_expr;
@@ -2344,12 +2362,15 @@ namespace Mono.CSharp {
                //
                // Creates fully resolved expression switcher
                //
-               public static Constant Create (Constant expr, Expression original_expr)
+               public static Constant Create (Constant expr, Expression originalExpr)
                {
                        if (expr.eclass == ExprClass.Unresolved)
                                throw new ArgumentException ("Unresolved expression");
 
-                       return new ReducedConstantExpression (expr, original_expr);
+                       if (originalExpr is ExpressionStatement)
+                               return new ReducedConstantStatement (expr, originalExpr);
+
+                       return new ReducedConstantExpression (expr, originalExpr);
                }
 
                public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
index 7868c6a2c9d49b576a63cc69b088fd6e9c722a2d..9c804ceca575e6730e194e54a8bce5735a24cb81 100644 (file)
@@ -217,8 +217,14 @@ namespace Mono.CSharp {
                                        return false;
 
                                statement = Expr as ExpressionStatement;
-                               if (statement == null)
-                                       Expr.Error_InvalidExpressionStatement (ec);
+                               if (statement == null) {
+                                       var reduced = Expr as IReducedExpressionStatement;
+                                       if (reduced != null) {
+                                               statement = EmptyExpressionStatement.Instance;
+                                       } else {
+                                               Expr.Error_InvalidExpressionStatement (ec);
+                                       }
+                               }
 
                                return true;
                        }
diff --git a/mcs/tests/gtest-633.cs b/mcs/tests/gtest-633.cs
new file mode 100644 (file)
index 0000000..32882ba
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+struct BB
+{}
+
+public class X
+{
+       public static void Main ()
+       {
+               // Reduced expression statements
+               
+               new BB? ();
+               new float();
+
+               Action a = () => new float();
+               a ();
+       }
+}
\ No newline at end of file
index 2a64b11127c258d98656489f0195317f72652589..47cfe2ca4691486b451b208e33ce53565de8a80e 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-633.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>38</size>
+      </method>
+      <method name="Void &lt;Main&gt;m__0()" attrs="145">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anontype-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">