[mcs] Don't reset temporary stack fields too early. Fixes #43265
authorMarek Safar <masafa@microsoft.com>
Mon, 15 Aug 2016 18:59:41 +0000 (20:59 +0200)
committerMarek Safar <masafa@microsoft.com>
Mon, 15 Aug 2016 19:13:30 +0000 (21:13 +0200)
mcs/mcs/async.cs
mcs/mcs/expression.cs
mcs/mcs/statement.cs
mcs/tests/test-async-87.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index b3efae3241024e39237558fbf7b0634d32f8a761..39d114fd451cb516dca4d5a8e9679e07ecf6a2ff 100644 (file)
@@ -973,14 +973,17 @@ namespace Mono.CSharp
                public StackFieldExpr (Field field)
                        : base (field, Location.Null)
                {
+                       AutomaticallyReuse = true;
                }
 
+               public bool AutomaticallyReuse { get; set; }
+
                public bool IsAvailableForReuse {
                        get {
                                var field = (Field) spec.MemberDefinition;
                                return field.IsAvailableForReuse;
                        }
-                       set {
+                       private set {
                                var field = (Field) spec.MemberDefinition;
                                field.IsAvailableForReuse = value;
                        }
@@ -990,7 +993,7 @@ namespace Mono.CSharp
                {
                        base.AddressOf (ec, mode);
 
-                       if (mode == AddressOp.Load) {
+                       if (mode == AddressOp.Load && AutomaticallyReuse) {
                                IsAvailableForReuse = true;
                        }
                }
@@ -999,7 +1002,8 @@ namespace Mono.CSharp
                {
                        base.Emit (ec);
 
-                       PrepareCleanup (ec);
+                       if (AutomaticallyReuse)
+                               PrepareCleanup (ec);
                }
 
                public void EmitLoad (EmitContext ec)
index f805523b76e0a16f41bd3320409ad98aba4cab8e..bc75f5388cd83848d520c9735078db8cda4a733c 100644 (file)
@@ -12251,6 +12251,7 @@ namespace Mono.CSharp
                                                throw new NotImplementedException ();
 
                                        sf = ec.GetTemporaryField (type);
+                                       sf.AutomaticallyReuse = false;
                                        sf.EmitAssign (ec, temp, false, false);
                                        temp_target = sf;
                                        temp.Release (ec);
@@ -12268,8 +12269,8 @@ namespace Mono.CSharp
                                temp.Release (ec);
 
                        if (sf != null)
-                               sf.IsAvailableForReuse = true;
-
+                               sf.PrepareCleanup (ec);
+                       
                        return true;
                }
 
index 703e7ba497fef805446a5df389a8fa4f81258816..ad08d02b5db754d3948bdb8ad9c4b690011c1aff 100644 (file)
@@ -7041,6 +7041,7 @@ namespace Mono.CSharp {
                        ec.Emit (OpCodes.Stloc, temp);
 
                        var exception_field = ec.GetTemporaryField (type);
+                       exception_field.AutomaticallyReuse = false;
                        ec.EmitThis ();
                        ec.Emit (OpCodes.Ldloc, temp);
                        exception_field.EmitAssignFromStack (ec);
@@ -7064,7 +7065,7 @@ namespace Mono.CSharp {
                        ec.Emit (OpCodes.Throw);
                        ec.MarkLabel (skip_throw);
 
-                       exception_field.IsAvailableForReuse = true;
+                       exception_field.PrepareCleanup (ec);
 
                        EmitUnwindFinallyTable (ec);
                }
diff --git a/mcs/tests/test-async-87.cs b/mcs/tests/test-async-87.cs
new file mode 100644 (file)
index 0000000..d973ba1
--- /dev/null
@@ -0,0 +1,55 @@
+using System;
+using System.Threading.Tasks;
+
+class CA
+{
+       public CB CB { get; set; }
+       public DeviceDetails DeviceDetails { get; set; }
+}
+
+class CB
+{
+       public CB (string arg)
+       {
+       }
+}
+
+class DeviceDetails
+{
+       public DeviceDetails (string arg)
+       {
+       }
+}
+
+class BB
+{
+       public Task<string> GetUser()
+       {        
+               return Task.FromResult ("aa");
+       }
+
+       public Task<string> GetDevice()
+       {
+               return Task.FromResult ("bb");
+       }    
+}
+
+class X
+{
+       BB bb = new BB ();
+
+       public async Task<CA> GetCAAsync()
+       {
+               return new CA
+               {
+                       CB = new CB(await bb.GetUser()),
+                       DeviceDetails = new DeviceDetails(await bb.GetDevice())
+               };
+       }
+
+       static void Main ()
+       {
+               var x = new X ();
+               x.GetCAAsync ().Wait ();
+       }
+}
\ No newline at end of file
index 33a932710a489b7be51602237e4abd76cb5ac242..3f25baf1abb1860e74023b10fe3e421fcd54da8c 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-async-87.cs">
+    <type name="CA">
+      <method name="CB get_CB()" attrs="2182">
+        <size>14</size>
+      </method>
+      <method name="Void set_CB(CB)" attrs="2182">
+        <size>8</size>
+      </method>
+      <method name="DeviceDetails get_DeviceDetails()" attrs="2182">
+        <size>14</size>
+      </method>
+      <method name="Void set_DeviceDetails(DeviceDetails)" attrs="2182">
+        <size>8</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="CB">
+      <method name="Void .ctor(String)" attrs="6278">
+        <size>8</size>
+      </method>
+    </type>
+    <type name="DeviceDetails">
+      <method name="Void .ctor(String)" attrs="6278">
+        <size>8</size>
+      </method>
+    </type>
+    <type name="BB">
+      <method name="System.Threading.Tasks.Task`1[System.String] GetUser()" attrs="134">
+        <size>19</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.String] GetDevice()" attrs="134">
+        <size>19</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="System.Threading.Tasks.Task`1[CA] GetCAAsync()" attrs="134">
+        <size>41</size>
+      </method>
+      <method name="Void Main()" attrs="145">
+        <size>19</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>18</size>
+      </method>
+    </type>
+    <type name="X+&lt;GetCAAsync&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>366</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">