From patchwork Tue Dec 14 05:57:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 75470 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 D92461007D1 for ; Tue, 14 Dec 2010 16:58:03 +1100 (EST) Received: (qmail 17982 invoked by alias); 14 Dec 2010 05:58:00 -0000 Received: (qmail 17972 invoked by uid 22791); 14 Dec 2010 05:57:59 -0000 X-SWARE-Spam-Status: No, hits=-4.7 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, 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.35) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 14 Dec 2010 05:57:52 +0000 Received: from kpbe18.cbf.corp.google.com (kpbe18.cbf.corp.google.com [172.25.105.82]) by smtp-out.google.com with ESMTP id oBE5vnEj008178 for ; Mon, 13 Dec 2010 21:57:49 -0800 Received: from iye19 (iye19.prod.google.com [10.241.50.19]) by kpbe18.cbf.corp.google.com with ESMTP id oBE5vmQG007521 for ; Mon, 13 Dec 2010 21:57:48 -0800 Received: by iye19 with SMTP id 19so154743iye.32 for ; Mon, 13 Dec 2010 21:57:48 -0800 (PST) Received: by 10.42.177.137 with SMTP id bi9mr3774719icb.275.1292306268107; Mon, 13 Dec 2010 21:57:48 -0800 (PST) Received: from coign.google.com (adsl-71-133-8-30.dsl.pltn13.pacbell.net [71.133.8.30]) by mx.google.com with ESMTPS id y8sm503893ica.14.2010.12.13.21.57.46 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 13 Dec 2010 21:57:47 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Fix parsing of type switches Date: Mon, 13 Dec 2010 21:57:44 -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 gccgo would incorrectly permit code like switch x := <-ch.(type) { case int: } This is invalid: a type switch has to just be expr.(type), not an expression on a type guard. This patch fixes the type switch parsing. In testing it I saw that the error reporting for an invalid type guard was pretty bad, so I fixed that up too. Bootstrapped and ran Go tests on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r a3c80279619e go/expressions.cc --- a/go/expressions.cc Mon Dec 13 21:17:25 2010 -0800 +++ b/go/expressions.cc Mon Dec 13 21:51:50 2010 -0800 @@ -11620,24 +11620,29 @@ this->report_error(_("invalid unsafe.Pointer conversion")); } else if (expr_type->interface_type() == NULL) - this->report_error(_("type assertion only valid for interface types")); + { + if (!expr_type->is_error_type() && !this->type_->is_error_type()) + this->report_error(_("type assertion only valid for interface types")); + this->set_is_error(); + } else if (this->type_->interface_type() == NULL) { std::string reason; if (!expr_type->interface_type()->implements_interface(this->type_, &reason)) { - if (reason.empty()) - this->report_error(_("impossible type assertion: " - "type does not implement interface")); - else + if (!this->type_->is_error_type()) { - error_at(this->location(), - ("impossible type assertion: " - "type does not implement interface (%s)"), - reason.c_str()); - this->set_is_error(); + if (reason.empty()) + this->report_error(_("impossible type assertion: " + "type does not implement interface")); + else + error_at(this->location(), + ("impossible type assertion: " + "type does not implement interface (%s)"), + reason.c_str()); } + this->set_is_error(); } } } diff -r a3c80279619e go/parse.cc --- a/go/parse.cc Mon Dec 13 21:17:25 2010 -0800 +++ b/go/parse.cc Mon Dec 13 21:51:50 2010 -0800 @@ -2647,12 +2647,18 @@ { this->advance_token(); Type* type = NULL; - if (is_type_switch == NULL - || !this->peek_token()->is_keyword(KEYWORD_TYPE)) + if (!this->peek_token()->is_keyword(KEYWORD_TYPE)) type = this->type(); else { - *is_type_switch = true; + if (is_type_switch != NULL) + *is_type_switch = true; + else + { + error_at(this->location(), + "use of %<.(type)%> outside type switch"); + type = Type::make_error_type(); + } this->advance_token(); } if (!this->peek_token()->is_op(OPERATOR_RPAREN)) @@ -2866,7 +2872,7 @@ left = this->verify_not_sink(left); Expression* right = this->expression(right_precedence, false, may_be_composite_lit, - is_type_switch); + NULL); if (op == OPERATOR_CHANOP) left = Expression::make_send(left, right, binop_location); else @@ -2959,8 +2965,7 @@ return Expression::make_type(this->type(), location); } - Expression* expr = this->unary_expr(false, may_be_composite_lit, - is_type_switch); + Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL); if (expr->is_error_expression()) ; else if (op == OPERATOR_MULT && expr->is_type_expression()) diff -r a3c80279619e go/statements.cc --- a/go/statements.cc Mon Dec 13 21:17:25 2010 -0800 +++ b/go/statements.cc Mon Dec 13 21:51:50 2010 -0800 @@ -1296,7 +1296,8 @@ Type* expr_type = this->expr_->type(); if (expr_type->interface_type() == NULL) { - this->report_error(_("type assertion only valid for interface types")); + if (!expr_type->is_error_type() && !this->type_->is_error_type()) + this->report_error(_("type assertion only valid for interface types")); return Statement::make_error_statement(loc); }