From patchwork Tue Jan 4 19:34:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 77516 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9DDF6B7105 for ; Wed, 5 Jan 2011 06:34:50 +1100 (EST) Received: (qmail 13598 invoked by alias); 4 Jan 2011 19:34:48 -0000 Received: (qmail 13326 invoked by uid 22791); 4 Jan 2011 19:34:47 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.67) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 04 Jan 2011 19:34:42 +0000 Received: from kpbe12.cbf.corp.google.com (kpbe12.cbf.corp.google.com [172.25.105.76]) by smtp-out.google.com with ESMTP id p04JYc94005323 for ; Tue, 4 Jan 2011 11:34:39 -0800 Received: from pxi17 (pxi17.prod.google.com [10.243.27.17]) by kpbe12.cbf.corp.google.com with ESMTP id p04JYSk9022696 for ; Tue, 4 Jan 2011 11:34:37 -0800 Received: by pxi17 with SMTP id 17so2466123pxi.25 for ; Tue, 04 Jan 2011 11:34:37 -0800 (PST) Received: by 10.142.82.8 with SMTP id f8mr17915218wfb.317.1294169677321; Tue, 04 Jan 2011 11:34:37 -0800 (PST) Received: from coign.google.com (dhcp-172-22-123-229.mtv.corp.google.com [172.22.123.229]) by mx.google.com with ESMTPS id w22sm31253537wfd.7.2011.01.04.11.34.36 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 04 Jan 2011 11:34:36 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Check for multiple default cases Date: Tue, 04 Jan 2011 11:34:34 -0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch to the Go frontend checks for multiple default cases in switch or select statements. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r 26cd50a7d613 go/parse.cc --- a/go/parse.cc Tue Jan 04 11:02:14 2011 -0800 +++ b/go/parse.cc Tue Jan 04 11:31:42 2011 -0800 @@ -3825,6 +3825,7 @@ this->push_break_statement(statement, label); Case_clauses* case_clauses = new Case_clauses(); + bool saw_default = false; while (!this->peek_token()->is_op(OPERATOR_RCURLY)) { if (this->peek_token()->is_eof()) @@ -3833,7 +3834,7 @@ error_at(this->location(), "missing %<}%>"); return NULL; } - this->expr_case_clause(case_clauses); + this->expr_case_clause(case_clauses, &saw_default); } this->advance_token(); @@ -3848,7 +3849,7 @@ // FallthroughStat = "fallthrough" . void -Parse::expr_case_clause(Case_clauses* clauses) +Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default) { source_location location = this->location(); @@ -3880,6 +3881,16 @@ this->advance_token(); } + if (is_default) + { + if (*saw_default) + { + error_at(location, "multiple defaults in switch"); + return; + } + *saw_default = true; + } + if (is_default || vals != NULL) clauses->add(vals, is_default, statements, is_fallthrough, location); } @@ -3936,6 +3947,7 @@ this->push_break_statement(statement, label); Type_case_clauses* case_clauses = new Type_case_clauses(); + bool saw_default = false; while (!this->peek_token()->is_op(OPERATOR_RCURLY)) { if (this->peek_token()->is_eof()) @@ -3943,7 +3955,7 @@ error_at(this->location(), "missing %<}%>"); return NULL; } - this->type_case_clause(switch_no, case_clauses); + this->type_case_clause(switch_no, case_clauses, &saw_default); } this->advance_token(); @@ -3957,7 +3969,8 @@ // TypeCaseClause = TypeSwitchCase ":" [ StatementList ] . void -Parse::type_case_clause(Named_object* switch_no, Type_case_clauses* clauses) +Parse::type_case_clause(Named_object* switch_no, Type_case_clauses* clauses, + bool* saw_default) { source_location location = this->location(); @@ -4000,6 +4013,12 @@ if (is_default) { gcc_assert(types.empty()); + if (*saw_default) + { + error_at(location, "multiple defaults in type switch"); + return; + } + *saw_default = true; clauses->add(NULL, false, true, statements, location); } else if (!types.empty()) @@ -4076,6 +4095,7 @@ this->push_break_statement(statement, label); Select_clauses* select_clauses = new Select_clauses(); + bool saw_default = false; while (!this->peek_token()->is_op(OPERATOR_RCURLY)) { if (this->peek_token()->is_eof()) @@ -4083,7 +4103,7 @@ error_at(this->location(), "expected %<}%>"); return; } - this->comm_clause(select_clauses); + this->comm_clause(select_clauses, &saw_default); } this->advance_token(); @@ -4098,7 +4118,7 @@ // CommClause = CommCase [ StatementList ] . void -Parse::comm_clause(Select_clauses* clauses) +Parse::comm_clause(Select_clauses* clauses, bool* saw_default) { source_location location = this->location(); bool is_send = false; @@ -4130,6 +4150,16 @@ statements = this->gogo_->finish_block(this->location()); } + if (is_default) + { + if (*saw_default) + { + error_at(location, "multiple defaults in select"); + return; + } + *saw_default = true; + } + if (got_case) clauses->add(is_send, channel, val, var, is_default, statements, location); } diff -r 26cd50a7d613 go/parse.h --- a/go/parse.h Tue Jan 04 11:02:14 2011 -0800 +++ b/go/parse.h Tue Jan 04 11:31:42 2011 -0800 @@ -238,14 +238,14 @@ void if_stat(); void switch_stat(const Label*); Statement* expr_switch_body(const Label*, Expression*, source_location); - void expr_case_clause(Case_clauses*); + void expr_case_clause(Case_clauses*, bool* saw_default); Expression_list* expr_switch_case(bool*); Statement* type_switch_body(const Label*, const Type_switch&, source_location); - void type_case_clause(Named_object*, Type_case_clauses*); + void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default); void type_switch_case(std::vector*, bool*); void select_stat(const Label*); - void comm_clause(Select_clauses*); + void comm_clause(Select_clauses*, bool* saw_default); bool comm_case(bool*, Expression**, Expression**, std::string*, bool*); bool send_or_recv_expr(bool*, Expression**, Expression**, std::string*); void for_stat(const Label*);