[mcs] Detect constant switch statement fall-through. Fixes #42585
authorMarek Safar <marek.safar@gmail.com>
Wed, 27 Jul 2016 09:40:49 +0000 (11:40 +0200)
committerMarek Safar <marek.safar@gmail.com>
Wed, 27 Jul 2016 09:40:49 +0000 (11:40 +0200)
mcs/errors/cs0163-2.cs [new file with mode: 0644]
mcs/mcs/statement.cs

diff --git a/mcs/errors/cs0163-2.cs b/mcs/errors/cs0163-2.cs
new file mode 100644 (file)
index 0000000..945ae8a
--- /dev/null
@@ -0,0 +1,13 @@
+// CS0163: Control cannot fall through from one case label `case 1:' to another
+// Line: 9
+
+public class Program
+{
+       public static void Main ()
+       {
+               switch (1) {
+                       case 1: {}
+                       default: {}
+               }
+       }
+}
\ No newline at end of file
index d0341cb3b633045c48889bfa3a3f31789df36ff0..703e7ba497fef805446a5df389a8fa4f81258816 100644 (file)
@@ -5378,18 +5378,30 @@ namespace Mono.CSharp {
                                                continue;
                                        }
 
-                                       if (constant_label != null && constant_label != sl)
+                                       if (section_rc.IsUnreachable) {
+                                               //
+                                               // Common case. Previous label section end is unreachable as
+                                               // it ends with break, return, etc. For next section revert
+                                               // to reachable again unless we have constant switch block
+                                               //
+                                               section_rc = constant_label != null && constant_label != sl ?
+                                                       Reachability.CreateUnreachable () :
+                                                       new Reachability ();
+                                       } else if (prev_label != null) {
+                                               //
+                                               // Error case as control cannot fall through from one case label
+                                               //
+                                               sl.SectionStart = false;
+                                               s = new MissingBreak (prev_label);
+                                               s.MarkReachable (rc);
+                                               block.Statements.Insert (i - 1, s);
+                                               ++i;
+                                       } else if (constant_label != null && constant_label != sl) {
+                                               //
+                                               // Special case for the first unreachable label in constant
+                                               // switch block
+                                               //
                                                section_rc = Reachability.CreateUnreachable ();
-                                       else if (section_rc.IsUnreachable) {
-                                               section_rc = new Reachability ();
-                                       } else {
-                                               if (prev_label != null) {
-                                                       sl.SectionStart = false;
-                                                       s = new MissingBreak (prev_label);
-                                                       s.MarkReachable (rc);
-                                                       block.Statements.Insert (i - 1, s);
-                                                       ++i;
-                                               }
                                        }
 
                                        prev_label = sl;