[mcs] Fix scope initialization for exception filters using hoisted lambdas with await...
authorMarek Safar <marek.safar@gmail.com>
Mon, 23 Jun 2014 15:39:54 +0000 (17:39 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 24 Jun 2014 12:20:15 +0000 (14:20 +0200)
mcs/mcs/statement.cs
mcs/tests/test-ex-filter-05.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 7f78fc2b5946905cb5e05a94b3fd7bbb1b8837f3..2239bfde58236d517ac8ac61bbaca7a459ddb211 100644 (file)
@@ -2663,7 +2663,8 @@ namespace Mono.CSharp {
                        FinallyBlock = 1 << 14,
                        CatchBlock = 1 << 15,
                        Iterator = 1 << 20,
-                       NoFlowAnalysis = 1 << 21
+                       NoFlowAnalysis = 1 << 21,
+                       InitializationEmitted = 1 << 22
                }
 
                public Block Parent;
@@ -2939,12 +2940,10 @@ namespace Mono.CSharp {
                        DoEmit (ec);
                }
 
-               public void EmitScopeInitializers (EmitContext ec)
+               protected void EmitScopeInitializers (EmitContext ec)
                {
                        foreach (Statement s in scope_initializers)
                                s.Emit (ec);
-
-                       scope_initializers = null;
                }
 
                protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
@@ -3182,8 +3181,11 @@ namespace Mono.CSharp {
                        return am_storey;
                }
 
-               public override void Emit (EmitContext ec)
+               public void EmitScopeInitialization (EmitContext ec)
                {
+                       if ((flags & Flags.InitializationEmitted) != 0)
+                               return;
+
                        if (am_storey != null) {
                                DefineStoreyContainer (ec, am_storey);
                                am_storey.EmitStoreyInstantiation (ec, this);
@@ -3192,6 +3194,13 @@ namespace Mono.CSharp {
                        if (scope_initializers != null)
                                EmitScopeInitializers (ec);
 
+                       flags |= Flags.InitializationEmitted;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       EmitScopeInitialization (ec);
+
                        if (ec.EmitAccurateDebugInfo && !IsCompilerGenerated && ec.Mark (StartLocation)) {
                                ec.Emit (OpCodes.Nop);
                        }
@@ -6471,7 +6480,7 @@ namespace Mono.CSharp {
                                        EmitCatchVariableStore (ec);
 
                                if (Block.HasAwait) {
-                                       Block.EmitScopeInitializers (ec);
+                                       Block.EmitScopeInitialization (ec);
                                } else {
                                        Block.Emit (ec);
                                }
diff --git a/mcs/tests/test-ex-filter-05.cs b/mcs/tests/test-ex-filter-05.cs
new file mode 100644 (file)
index 0000000..5d1251a
--- /dev/null
@@ -0,0 +1,40 @@
+using System;
+using System.Threading.Tasks;
+
+class Test
+{
+       static bool Verify (Func<bool> f)
+       {
+               return f ();
+       }
+
+       static async Task<int> TestCapturedException (Exception e)
+       {
+               try {
+                       if (e != null)
+                               throw e;
+               } catch (Exception ex) if (Verify (() => ex.Message == "foo")) {
+                       await Task.Yield ();
+                       Console.WriteLine (ex);
+                       return 1;
+               } catch (Exception ex) if (Verify (() => ex.Message != null)) {
+                       await Task.Yield ();
+                       Console.WriteLine (ex);
+                       return 2;
+               }
+
+               return 3;
+       }
+
+       public static int Main()
+       {
+               if (TestCapturedException (null).Result != 3)
+                       return 1;
+
+               var ex = new ApplicationException ();
+               if (TestCapturedException (ex).Result != 2)
+                       return 2;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 6b96d472d903c6640208987fe45336aef0a1c330..6bbe605e2875a57b6c2052f142630173ce30537f 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-ex-filter-05.cs">\r
+    <type name="Test">\r
+      <method name="Boolean Verify(System.Func`1[System.Boolean])" attrs="145">\r
+        <size>15</size>\r
+      </method>\r
+      <method name="System.Threading.Tasks.Task`1[System.Int32] TestCapturedException(System.Exception)" attrs="145">\r
+        <size>41</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>64</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test+&lt;TestCapturedException&gt;c__async0">\r
+      <method name="Void MoveNext()" attrs="486">\r
+        <size>491</size>\r
+      </method>\r
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+        <size>13</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test+&lt;TestCapturedException&gt;c__async0+&lt;TestCapturedException&gt;c__AnonStorey1">\r
+      <method name="Boolean &lt;&gt;m__0()" attrs="131">\r
+        <size>29</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test+&lt;TestCapturedException&gt;c__async0+&lt;TestCapturedException&gt;c__AnonStorey2">\r
+      <method name="Boolean &lt;&gt;m__0()" attrs="131">\r
+        <size>25</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-externalias-01.cs">\r
     <type name="Test">\r
       <method name="Int32 Main()" attrs="150">\r