From patchwork Fri Oct 3 15:14:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 396272 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C098E14017D for ; Sat, 4 Oct 2014 01:15:03 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=SyuqzZr2ItSdzyvQPfTePziMThy69/oMhFAhzHbw0jl+aW4lpnTJO 9ec3f9GZkHXo0KHPfR3QZxpR5GZQ01AuXgxhAMXM1VD0Eyfpphd2Y5LEy1YBpOhs nkG6v1baa4K66+L8m9FhSOF8fDnwqXBGyndlkf2+y+Gd7mhyFtU/hw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=w+f1gG8NoR87/RpKtPM/Y7Dy+ZE=; b=sHP6LcUzZxS87SSoDGev 8moplTphm99MgNXi8l+dydgiFl3qXGA5i6TZotXCQbpAHQWZFJfAwEw96Kji6kC5 e0mdcs9qDuiwdXldzjluHYZK/a50ZIzZb1UZks31TgW/lV7Kf8pMaeXb/53Zlxq8 MpQGlFBV00McVLa3cXkmFVw= Received: (qmail 8809 invoked by alias); 3 Oct 2014 15:14:57 -0000 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 Received: (qmail 8798 invoked by uid 89); 3 Oct 2014 15:14:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f50.google.com Received: from mail-pa0-f50.google.com (HELO mail-pa0-f50.google.com) (209.85.220.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 03 Oct 2014 15:14:55 +0000 Received: by mail-pa0-f50.google.com with SMTP id kx10so1709257pab.9 for ; Fri, 03 Oct 2014 08:14:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version:content-type; bh=t37CnTLbQt+HEi0/zYFMnY2yLVgckofr2AnuoSU1650=; b=cDbXFr1ov1Vdo6ohQLSdymeGN7zKsb8uYH6QiWIDbCJ316QrZm2u1s7+Xy7Jb9YhJK nVUryfTstdIy+EZ5PDdDtVYdGtuRLoKkQz95RaQtdhtisC8LM7HgONcB6UONJs3ldra6 JZXnkeBM7Aq7EMn3CgaKbVbCDuAH7w9JdlMXdbWAqy3LmMLpg6QvQf5kciOOXJUPa+Ez D0gJTSRIYquYIuui7Vt+3gwEx1JxrMjEeDelCjEodJQoHyRd44MUrSIP/jwCA4YDb/5X 8KLi5+4UR/b65cSsyHet9VC5xMC5ruIGQtLVSeeNE6dh8c3V46+STA34fUpzgfxA8c6l l5CQ== X-Gm-Message-State: ALoCoQmGI2DKV7ldep7fQ+I6Z4v8VrXsSNbjL1GxfJTmbFkGVPVSOI64OX6i2T+iBmOPshTxIMeV X-Received: by 10.70.45.107 with SMTP id l11mr1306799pdm.141.1412349293481; Fri, 03 Oct 2014 08:14:53 -0700 (PDT) Received: from iant-glaptop.roam.corp.google.com.google.com ([2620:0:1000:157d:c1e1:8ec0:ad7a:27e6]) by mx.google.com with ESMTPSA id bl3sm4422122pdb.53.2014.10.03.08.14.52 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 03 Oct 2014 08:14:52 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Don't confuse fields and promoted methods Date: Fri, 03 Oct 2014 08:14:51 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes This patch from Tim Shen fixes a bug in the Go frontend in which a promoted method could be used even if there was a field of the same name. This fixes http://golang.org/issue/4365 . Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r c9d064a071c9 go/types.cc --- a/go/types.cc Fri Oct 03 08:11:52 2014 -0700 +++ b/go/types.cc Fri Oct 03 08:12:08 2014 -0700 @@ -9387,9 +9387,14 @@ Type::finalize_methods(Gogo* gogo, const Type* type, Location location, Methods** all_methods) { - *all_methods = NULL; + *all_methods = new Methods(); std::vector seen; - Type::add_methods_for_type(type, NULL, 0, false, false, &seen, all_methods); + Type::add_methods_for_type(type, NULL, 0, false, false, &seen, *all_methods); + if ((*all_methods)->empty()) + { + delete *all_methods; + *all_methods = NULL; + } Type::build_stub_methods(gogo, type, *all_methods, location); } @@ -9408,7 +9413,7 @@ bool is_embedded_pointer, bool needs_stub_method, std::vector* seen, - Methods** methods) + Methods* methods) { // Pointer types may not have methods. if (type->points_to() != NULL) @@ -9457,15 +9462,12 @@ unsigned int depth, bool is_embedded_pointer, bool needs_stub_method, - Methods** methods) + Methods* methods) { const Bindings* local_methods = nt->local_methods(); if (local_methods == NULL) return; - if (*methods == NULL) - *methods = new Methods(); - for (Bindings::const_declarations_iterator p = local_methods->begin_declarations(); p != local_methods->end_declarations(); @@ -9476,7 +9478,7 @@ || !Type::method_expects_pointer(no)); Method* m = new Named_method(no, field_indexes, depth, is_value_method, (needs_stub_method || depth > 0)); - if (!(*methods)->insert(no->name(), m)) + if (!methods->insert(no->name(), m)) delete m; } } @@ -9492,7 +9494,7 @@ bool is_embedded_pointer, bool needs_stub_method, std::vector* seen, - Methods** methods) + Methods* methods) { // Look for anonymous fields in TYPE. TYPE has fields if it is a // struct. @@ -9530,13 +9532,35 @@ sub_field_indexes->next = field_indexes; sub_field_indexes->field_index = i; + Methods tmp_methods; Type::add_methods_for_type(fnt, sub_field_indexes, depth + 1, (is_embedded_pointer || is_pointer), (needs_stub_method || is_pointer || i > 0), seen, - methods); + &tmp_methods); + // Check if there are promoted methods that conflict with field names and + // don't add them to the method map. + for (Methods::const_iterator p = tmp_methods.begin(); + p != tmp_methods.end(); + ++p) + { + bool found = false; + for (Struct_field_list::const_iterator fp = fields->begin(); + fp != fields->end(); + ++fp) + { + if (fp->field_name() == p->first) + { + found = true; + break; + } + } + if (!found && + !methods->insert(p->first, p->second)) + delete p->second; + } } } @@ -9548,7 +9572,7 @@ Type::add_interface_methods_for_type(const Type* type, const Method::Field_indexes* field_indexes, unsigned int depth, - Methods** methods) + Methods* methods) { const Interface_type* it = type->interface_type(); if (it == NULL) @@ -9558,9 +9582,6 @@ if (imethods == NULL) return; - if (*methods == NULL) - *methods = new Methods(); - for (Typed_identifier_list::const_iterator pm = imethods->begin(); pm != imethods->end(); ++pm) @@ -9576,7 +9597,7 @@ fntype = fntype->copy_with_receiver(const_cast(type)); Method* m = new Interface_method(pm->name(), pm->location(), fntype, field_indexes, depth); - if (!(*methods)->insert(pm->name(), m)) + if (!methods->insert(pm->name(), m)) delete m; } } diff -r c9d064a071c9 go/types.h --- a/go/types.h Fri Oct 03 08:11:52 2014 -0700 +++ b/go/types.h Fri Oct 03 08:12:08 2014 -0700 @@ -384,6 +384,10 @@ find(const std::string& name) const { return this->methods_.find(name); } + bool + empty() const + { return this->methods_.empty(); } + private: Method_map methods_; }; @@ -1228,24 +1232,24 @@ add_methods_for_type(const Type* type, const Method::Field_indexes*, unsigned int depth, bool, bool, std::vector*, - Methods**); + Methods*); static void add_local_methods_for_type(const Named_type* type, const Method::Field_indexes*, - unsigned int depth, bool, bool, Methods**); + unsigned int depth, bool, bool, Methods*); static void add_embedded_methods_for_type(const Type* type, const Method::Field_indexes*, unsigned int depth, bool, bool, std::vector*, - Methods**); + Methods*); static void add_interface_methods_for_type(const Type* type, const Method::Field_indexes*, - unsigned int depth, Methods**); + unsigned int depth, Methods*); // Build stub methods for a type. static void