From 3fab4bc11156e11c5ef3b3a4f754276e003c7ea9 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Wed, 27 Jul 2016 11:40:49 +0200 Subject: [PATCH] [mcs] Detect constant switch statement fall-through. Fixes #42585 --- mcs/errors/cs0163-2.cs | 13 +++++++++++++ mcs/mcs/statement.cs | 34 +++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 mcs/errors/cs0163-2.cs diff --git a/mcs/errors/cs0163-2.cs b/mcs/errors/cs0163-2.cs new file mode 100644 index 00000000000..945ae8ad094 --- /dev/null +++ b/mcs/errors/cs0163-2.cs @@ -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 diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index d0341cb3b63..703e7ba497f 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -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; -- 2.25.1