From patchwork Tue Dec 14 20:53:49 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: 75546 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 2BFC8B6F07 for ; Wed, 15 Dec 2010 07:54:12 +1100 (EST) Received: (qmail 22232 invoked by alias); 14 Dec 2010 20:54:06 -0000 Received: (qmail 22185 invoked by uid 22791); 14 Dec 2010 20:54:02 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CC, 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) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 14 Dec 2010 20:53:56 +0000 Received: from hpaq11.eem.corp.google.com (hpaq11.eem.corp.google.com [172.25.149.11]) by smtp-out.google.com with ESMTP id oBEKrrXt006108 for ; Tue, 14 Dec 2010 12:53:54 -0800 Received: from pxi6 (pxi6.prod.google.com [10.243.27.6]) by hpaq11.eem.corp.google.com with ESMTP id oBEKrpkT002347 for ; Tue, 14 Dec 2010 12:53:52 -0800 Received: by pxi6 with SMTP id 6so248565pxi.3 for ; Tue, 14 Dec 2010 12:53:51 -0800 (PST) Received: by 10.143.27.29 with SMTP id e29mr4978549wfj.336.1292360031493; Tue, 14 Dec 2010 12:53:51 -0800 (PST) Received: from coign.google.com (dhcp-172-22-122-182.mtv.corp.google.com [172.22.122.182]) by mx.google.com with ESMTPS id f5sm571077wfg.2.2010.12.14.12.53.50 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 14 Dec 2010 12:53:51 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Fix unknown name in map composite literal Date: Tue, 14 Dec 2010 12:53:49 -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 When an unknown name was used as the key in a map composite literal, gccgo would crash. This patch fixes the problem. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r b5cc75949123 go/types.cc --- a/go/types.cc Tue Dec 14 11:34:18 2010 -0800 +++ b/go/types.cc Tue Dec 14 12:47:02 2010 -0800 @@ -53,9 +53,9 @@ switch (this->classification_) { case TYPE_NAMED: - return static_cast(this)->real_type()->base(); + return this->named_type()->named_base(); case TYPE_FORWARD: - return static_cast(this)->real_type()->base(); + return this->forward_declaration_type()->real_type()->base(); default: return this; } @@ -67,13 +67,9 @@ switch (this->classification_) { case TYPE_NAMED: - return static_cast(this)->real_type()->base(); + return this->named_type()->named_base(); case TYPE_FORWARD: - { - const Forward_declaration_type* ftype = - static_cast(this); - return ftype->real_type()->base(); - } + return this->forward_declaration_type()->real_type()->base(); default: return this; } @@ -224,7 +220,7 @@ case TYPE_ERROR: return true; case TYPE_NAMED: - return t->named_type()->real_type()->is_error_type(); + return t->named_type()->is_named_error_type(); default: return false; } @@ -5502,10 +5498,23 @@ const Typed_identifier* p = &this->methods_->at(from); if (!p->name().empty()) { - if (from != to) - this->methods_->set(to, *p); + size_t i = 0; + for (i = 0; i < to; ++i) + { + if (this->methods_->at(i).name() == p->name()) + { + error_at(p->location(), "duplicate method %qs", + Gogo::message_name(p->name()).c_str()); + break; + } + } + if (i == to) + { + if (from != to) + this->methods_->set(to, *p); + ++to; + } ++from; - ++to; continue; } Interface_type* it = p->type()->interface_type(); @@ -6448,6 +6457,45 @@ return this->named_object_->message_name(); } +// Return the base type for this type. We have to be careful about +// circular type definitions, which are invalid but may be seen here. + +Type* +Named_type::named_base() +{ + if (this->seen_) + return this; + this->seen_ = true; + Type* ret = this->type_->base(); + this->seen_ = false; + return ret; +} + +const Type* +Named_type::named_base() const +{ + if (this->seen_) + return this; + this->seen_ = true; + const Type* ret = this->type_->base(); + this->seen_ = false; + return ret; +} + +// Return whether this is an error type. We have to be careful about +// circular type definitions, which are invalid but may be seen here. + +bool +Named_type::is_named_error_type() const +{ + if (this->seen_) + return false; + this->seen_ = true; + bool ret = this->type_->is_error_type(); + this->seen_ = false; + return ret; +} + // Add a method to this type. Named_object* diff -r b5cc75949123 go/types.h --- a/go/types.h Tue Dec 14 11:34:18 2010 -0800 +++ b/go/types.h Tue Dec 14 12:47:02 2010 -0800 @@ -2457,6 +2457,17 @@ is_builtin() const { return this->location_ == BUILTINS_LOCATION; } + // Return the base type for this type. + Type* + named_base(); + + const Type* + named_base() const; + + // Return whether this is an error type. + bool + is_named_error_type() const; + // Add a method to this type. Named_object* add_method(const std::string& name, Function*);