[mcs] Reachability analysis should ignore local variables declarations. Fixes #20603
authorMarek Safar <marek.safar@gmail.com>
Mon, 16 Jun 2014 09:56:57 +0000 (11:56 +0200)
committerMarek Safar <marek.safar@gmail.com>
Mon, 16 Jun 2014 09:56:57 +0000 (11:56 +0200)
mcs/mcs/statement.cs
mcs/tests/test-896.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index ced42136ea55b696914b03b723aca60c8fae31de..a09c4acd939b99b5262234bdac40c46019aa09ce 100644 (file)
@@ -2186,13 +2186,13 @@ namespace Mono.CSharp {
                {
                        li.CreateBuilder (ec);
 
-                       if (Initializer != null)
+                       if (Initializer != null && !IsUnreachable)
                                ((ExpressionStatement) Initializer).EmitStatement (ec);
 
                        if (declarators != null) {
                                foreach (var d in declarators) {
                                        d.Variable.CreateBuilder (ec);
-                                       if (d.Initializer != null) {
+                                       if (d.Initializer != null && !IsUnreachable) {
                                                ec.Mark (d.Variable.Location);
                                                ((ExpressionStatement) d.Initializer).EmitStatement (ec);
                                        }
@@ -2925,7 +2925,7 @@ namespace Mono.CSharp {
 
                                end_unreachable = s.FlowAnalysis (fc);
                                if (s.IsUnreachable) {
-                                       statements[startIndex] = new EmptyStatement (s.loc);
+                                       statements [startIndex] = RewriteUnreachableStatement (s);
                                        continue;
                                }
 
@@ -2952,7 +2952,7 @@ namespace Mono.CSharp {
 
                                                if (s.IsUnreachable) {
                                                        s.FlowAnalysis (fc);
-                                                       statements[startIndex] = new EmptyStatement (s.loc);
+                                                       statements [startIndex] = RewriteUnreachableStatement (s);
                                                }
                                        }
                                }
@@ -2967,6 +2967,24 @@ namespace Mono.CSharp {
                        return !Explicit.HasReachableClosingBrace;
                }
 
+               static Statement RewriteUnreachableStatement (Statement s)
+               {
+                       // LAMESPEC: It's not clear whether declararion statement should be part of reachability
+                       // analysis. Even csc report unreachable warning for it but it's actually used hence
+                       // we try to emulate this behaviour
+                       //
+                       // Consider:
+                       //      goto L;
+                       //      int v;
+                       // L:
+                       //      v = 1;
+
+                       if (s is BlockVariable)
+                               return s;
+
+                       return new EmptyStatement (s.loc);
+               }
+
                public void ScanGotoJump (Statement label)
                {
                        int i;
@@ -6938,6 +6956,7 @@ namespace Mono.CSharp {
                        public VariableDeclaration (LocalVariable li, Location loc)
                                : base (li)
                        {
+                               reachable = true;
                                this.loc = loc;
                        }
 
@@ -7380,6 +7399,7 @@ namespace Mono.CSharp {
                                public RuntimeDispose (LocalVariable lv, Location loc)
                                        : base (lv, loc)
                                {
+                                       reachable = true;
                                }
 
                                protected override void CheckIDiposableConversion (BlockContext bc, LocalVariable li, Expression initializer)
diff --git a/mcs/tests/test-896.cs b/mcs/tests/test-896.cs
new file mode 100644 (file)
index 0000000..4336bf7
--- /dev/null
@@ -0,0 +1,13 @@
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               goto L1;
+               int z;
+       L1: 
+               z = 3;
+               Console.WriteLine (z);
+       }
+}
\ No newline at end of file
index b9acb70491d8302d92be4ee585cad93374423884..97366458344bab69fb156aa464139cdb0f3a0b16 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-896.cs">\r
+    <type name="Program">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>15</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-9.cs">\r
     <type name="X">\r
       <method name="Int32 Main(System.String[])" attrs="150">\r