compiler: permit empty statements after fallthrough
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 5 Feb 2018 01:53:23 +0000 (01:53 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 5 Feb 2018 01:53:23 +0000 (01:53 +0000)
    The language spec permits empty statements after a fallthrough
    statement, so implement that.  Also give a better error message when a
    fallthrough statement is in the wrong place.  The test case for this
    is in the master repository, test/fixedbugs/issue14540.go, just not
    yet in the gccgo repository.

    Fixes golang/go#14538

    Reviewed-on: https://go-review.googlesource.com/91855

From-SVN: r257378

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/parse.cc

index 575756eae5a3ec55a35b8bec3393080040cc7e04..c0f977a44c4b9a885c73afe761bff4e5872a050b 100644 (file)
@@ -1,4 +1,4 @@
-5031f878a761bf83f5f96710d62f83e2dc5ecf04
+d9f33a479f8012f7495d197e4b7417cba4d477fa
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 9700cc34363a34303303d2493802acd1ff5d308e..cc3791bb84da8f5c90b6e9906577b8c51ebf8df2 100644 (file)
@@ -4667,11 +4667,26 @@ Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
     {
       Location fallthrough_loc = this->location();
       is_fallthrough = true;
-      if (this->advance_token()->is_op(OPERATOR_SEMICOLON))
-       this->advance_token();
+      while (this->advance_token()->is_op(OPERATOR_SEMICOLON))
+       ;
       if (this->peek_token()->is_op(OPERATOR_RCURLY))
        go_error_at(fallthrough_loc,
                    _("cannot fallthrough final case in switch"));
+      else if (!this->peek_token()->is_keyword(KEYWORD_CASE)
+              && !this->peek_token()->is_keyword(KEYWORD_DEFAULT))
+       {
+         go_error_at(fallthrough_loc, "fallthrough statement out of place");
+         while (!this->peek_token()->is_keyword(KEYWORD_CASE)
+                && !this->peek_token()->is_keyword(KEYWORD_DEFAULT)
+                && !this->peek_token()->is_op(OPERATOR_RCURLY)
+                && !this->peek_token()->is_eof())
+           {
+             if (this->statement_may_start_here())
+               this->statement_list();
+             else
+               this->advance_token();
+           }
+       }
     }
 
   if (is_default)