Set resume point correctly for await inside nested try
authorMarek Safar <marek.safar@gmail.com>
Fri, 27 Jul 2012 07:59:57 +0000 (08:59 +0100)
committerMarek Safar <marek.safar@gmail.com>
Fri, 27 Jul 2012 07:59:57 +0000 (08:59 +0100)
mcs/mcs/flowanalysis.cs
mcs/mcs/iterators.cs
mcs/tests/test-async-37.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 5efeccb8fb612cac28e11157553ff4285aa1dc45..3cded948b00bcd5af3f3a9f31dcc26973bc75da9 100644 (file)
@@ -422,9 +422,9 @@ namespace Mono.CSharp
                        return Parent.CheckRethrow (loc);
                }
 
-               public virtual bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public virtual bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
-                       return Parent.AddResumePoint (stmt, out pc);
+                       return Parent.AddResumePoint (stmt, current, out pc);
                }
 
                // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
@@ -651,9 +651,9 @@ namespace Mono.CSharp
                        this.iterator = iterator;
                }
 
-               public override bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
-                       pc = iterator.AddResumePoint (stmt);
+                       pc = iterator.AddResumePoint (current);
                        return false;
                }
        }
@@ -673,7 +673,7 @@ namespace Mono.CSharp
                        return false;
                }
 
-               public override bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
                        throw new InternalErrorException ("A yield in a non-iterator block");
                }
@@ -750,16 +750,16 @@ namespace Mono.CSharp
                        return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc);
                }
 
-               public override bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
                        int errors = Report.Errors;
-                       Parent.AddResumePoint (tc.IsTryCatchFinally ? stmt : tc, out pc);
+                       Parent.AddResumePoint (stmt, tc.IsTryCatchFinally ? current : tc, out pc);
                        if (errors == Report.Errors) {
                                if (stmt is AwaitStatement) {
                                        if (CurrentUsageVector.Next != null) {
                                                Report.Error (1985, stmt.loc, "The `await' operator cannot be used in the body of a catch clause");
                                        } else {
-                                               this.tc.AddResumePoint (stmt, pc);
+                                               this.tc.AddResumePoint (current, pc);
                                        }
                                } else {
                                        if (CurrentUsageVector.Next == null)
@@ -815,9 +815,9 @@ namespace Mono.CSharp
                        return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc);
                }
 */
-               public override bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
-                       pc = async_init.AddResumePoint (stmt);
+                       pc = async_init.AddResumePoint (current);
                        return true;
                }
 
@@ -969,13 +969,13 @@ namespace Mono.CSharp
                        return false;
                }
 
-               public override bool AddResumePoint (ResumableStatement stmt, out int pc)
+               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
                {
                        int errors = Report.Errors;
-                       Parent.AddResumePoint (this.stmt, out pc);
+                       Parent.AddResumePoint (stmt, this.stmt, out pc);
                        if (errors == Report.Errors) {
                                if (finally_vector == null)
-                                       this.stmt.AddResumePoint (stmt, pc);
+                                       this.stmt.AddResumePoint (current, pc);
                                else {
                                        if (stmt is AwaitStatement) {
                                                Report.Error (1984, stmt.loc, "The `await' operator cannot be used in the body of a finally clause");
index 9334ec1e6b242da394e30aef0a76c1d959504d6f..dcbf10edf722bb4a6bf635406f9e62d75466939f 100644 (file)
@@ -60,7 +60,7 @@ namespace Mono.CSharp
                        machine_initializer = bc.CurrentAnonymousMethod as T;
 
                        if (!bc.CurrentBranching.CurrentUsageVector.IsUnreachable)
-                               unwind_protect = bc.CurrentBranching.AddResumePoint (this, out resume_pc);
+                               unwind_protect = bc.CurrentBranching.AddResumePoint (this, this, out resume_pc);
 
                        return true;
                }
diff --git a/mcs/tests/test-async-37.cs b/mcs/tests/test-async-37.cs
new file mode 100644 (file)
index 0000000..4ee0b4a
--- /dev/null
@@ -0,0 +1,31 @@
+using System;
+using System.Collections;
+using System.Threading.Tasks;
+
+class C
+{
+       static async Task<int> Test ()
+       {
+               var t = new Task<int> (() => { throw new ApplicationException ();});
+               try {
+                       try {
+                               t.Start ();
+                               await t;
+                       } catch {
+                               throw;
+                       }
+                       return -1;
+               } catch {
+                       return 1;
+               }   
+       }
+
+       public static int Main ()
+       {
+               var res = Test ().Result;
+               if (res != 1)
+                       return 1;
+               
+               return 0;
+       }
+}
index d914e52d437b8790d8164aee3c425279b64ebdb6..8ac1c7cae7c72a745abcaf3511b59c3a6363c3ae 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-async-37.cs">\r
+    <type name="C">\r
+      <method name="System.Threading.Tasks.Task`1[System.Int32] Test()" attrs="145">\r
+        <size>33</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>35</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="C+&lt;Test&gt;c__async0">\r
+      <method name="Void MoveNext()" attrs="486">\r
+        <size>272</size>\r
+      </method>\r
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
+        <size>13</size>\r
+      </method>\r
+      <method name="Int32 &lt;&gt;m__0()" attrs="145">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-cls-00.cs">\r
     <type name="CLSCLass_6">\r
       <method name="Void add_Disposed(Delegate)" attrs="2182">\r