[mcs] Codegen for optimized new with valuetype load and awaited arguments. Fixes...
authorMarek Safar <marek.safar@gmail.com>
Fri, 26 May 2017 16:22:58 +0000 (18:22 +0200)
committerMarek Safar <marek.safar@gmail.com>
Fri, 26 May 2017 16:24:35 +0000 (18:24 +0200)
mcs/mcs/expression.cs
mcs/tests/test-async-92.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index c054330db202f339be76b7a07f01626fd207f7fe..9042dcdabad8e5405cbbbc086953ade32d7dfc81 100644 (file)
@@ -7570,14 +7570,21 @@ namespace Mono.CSharp
                        bool is_value_type = type.IsStructOrEnum;
                        VariableReference vr = target as VariableReference;
 
+                       bool prepare_await = ec.HasSet (BuilderContext.Options.AsyncBody) && arguments?.ContainsEmitWithAwait () == true;
+
                        if (target != null && is_value_type && (vr != null || method == null)) {
+                               if (prepare_await) {
+                                       arguments = arguments.Emit (ec, false, true);
+                                       prepare_await = false;
+                               }
+                               
                                target.AddressOf (ec, AddressOp.Store);
                        } else if (vr != null && vr.IsRef) {
                                vr.EmitLoad (ec);
                        }
 
                        if (arguments != null) {
-                               if (ec.HasSet (BuilderContext.Options.AsyncBody) && (arguments.Count > (this is NewInitialize ? 0 : 1)) && arguments.ContainsEmitWithAwait ())
+                               if (prepare_await)
                                        arguments = arguments.Emit (ec, false, true);
 
                                arguments.Emit (ec);
diff --git a/mcs/tests/test-async-92.cs b/mcs/tests/test-async-92.cs
new file mode 100644 (file)
index 0000000..e41ac00
--- /dev/null
@@ -0,0 +1,22 @@
+using System.Threading.Tasks;
+
+public class A
+{
+       public async Task<ValueType> Test1 (int input2)
+       {
+               return new ValueType (await Task.FromResult (12345));
+       }
+
+       public static void Main ()
+       {
+               var a = new A ();
+               a.Test1 (1).Wait ();
+       }
+}
+
+public struct ValueType
+{
+       public ValueType (int field2)
+       {
+       }
+}
index 4882b788602ee9e5fb99495bac6bd98d1c8d546c..b06aba48fd5ead3c9127195304de99dfdf14ce4f 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-943.cs">
+    <type name="MyStruct">
+      <method name="Int32 get_X()" attrs="2182">
+        <size>14</size>
+      </method>
+      <method name="Void set_X(Int32)" attrs="2182">
+        <size>8</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="Int32 Main()" attrs="150">
+        <size>44</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-95.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
       </method>
     </type>
   </test>
+  <test name="test-async-92.cs">
+    <type name="A">
+      <method name="System.Threading.Tasks.Task`1[ValueType] Test1(Int32)" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>20</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="ValueType">
+      <method name="Void .ctor(Int32)" attrs="6278">
+        <size>2</size>
+      </method>
+    </type>
+    <type name="A+&lt;Test1&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>174</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">