From patchwork Mon Jul 19 23:48:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 1507324 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=vkFUKCIP; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GTJTN6Ng1z9sS8 for ; Tue, 20 Jul 2021 09:48:55 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 627C73972034 for ; Mon, 19 Jul 2021 23:48:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 627C73972034 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1626738532; bh=/fKm+KwsAN/qsd54+AY1Lkt7ZwG9TwZHGdUwxjZkwsA=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=vkFUKCIPmoqe0a45bhn43BynzVoecjI8ufPgTBJXM0TTss2VhEVALBKKgBp5hV/1d zais7KIKGzJAZt9ITHyisaN9LcS+zzN2AEv7eD8DaDXWm21CM66TTxgMdXXLfBrUmz tEZGzLtgqpDZmkrJvQYSZM8vbaj1GGAo81BoEDKI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by sourceware.org (Postfix) with ESMTPS id A37E1385C403 for ; Mon, 19 Jul 2021 23:48:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A37E1385C403 Received: by mail-ed1-x529.google.com with SMTP id dj21so26373597edb.0 for ; Mon, 19 Jul 2021 16:48:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=/fKm+KwsAN/qsd54+AY1Lkt7ZwG9TwZHGdUwxjZkwsA=; b=uPnMZ0rkWGrjpvbpm1J0hG6scbDwh5Xj9U3tEDfJ2rITusk9/HmJRsdpGV7BQBlDlO DevnpKe1OBIMUQM26CelNqpb/usPadhgYWCMgRsXjN9Swqn8LSicrwvFP35xcJdHGzXC PLgjY8oxuYD/rJuRI1rn0odyv5dQz2KguhZ2MXzafZ4fGUYScUw4urPQK5C6KGexrf6V V9ZWdZjmISIXWkGeTHn0WEyrprfEghuEX1nKxxwuqj/X5C6sk6qZ4QigAwMBdgHPhqL2 mL26R5wB/6lFf+uXz1+Jb4GAMQ4wrVvNdejxhKwQ5M7vAxSHFp1hiuSrPdoDVyAZH8F6 LMsQ== X-Gm-Message-State: AOAM532BWMBkOKUOVk6ghfaBli9Rh0dtnLmpcnuiNntrr01YWMTqK+t7 WfWR1Hf4jBFLho6Te9gDxXRJqsmq9i7noLNMMKSzbKRqQmXinQ== X-Google-Smtp-Source: ABdhPJwQJzqRhcKtLIvmn/Ly/5O+ZWyumryxdov33SA+51ZfFBnmAhaWLpIi5YNPvkjElqxtUzbgZFvmrwP7LaBBS+s= X-Received: by 2002:a05:6402:1488:: with SMTP id e8mr37381906edv.341.1626738509318; Mon, 19 Jul 2021 16:48:29 -0700 (PDT) MIME-Version: 1.0 Date: Mon, 19 Jul 2021 16:48:18 -0700 Message-ID: Subject: Go patch committed: Avoid aliases in receiver types To: gcc-patches , gofrontend-dev X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Ian Lance Taylor via Gcc-patches From: Ian Lance Taylor Reply-To: Ian Lance Taylor Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch changes the Go frontend to avoid aliases in receiver types. If a package declares a method on an alias type, the alias would be used in the export data. This would then trigger a compiler assertion on import: we should not be adding methods to aliases. Fix the problem by ensuring that receiver types do not use alias types. This seems preferable to consistently avoiding aliases in export data, as aliases can cross packages. And it's painful to try to patch this while writing the export data, as at that point all the types are known. The test case is https://golang.org/cl/335172. This fixes https://golang.org/issue/47131. Committed to mainline and GCC 11 branch. Ian 4b127b4deca54805da5628839926cd6c9ed2aeac diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4d0f44f2dd2..5323e186eab 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -adcf10890833026437a94da54934ce50c0018309 +920549b6382a2623538d31001271941f0e9e5a51 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 2872d2ed3ab..95b76bd317c 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5763,6 +5763,26 @@ Function::check_labels() const } } +// Set the receiver type. This is used to remove aliases. + +void +Function::set_receiver_type(Type* rtype) +{ + Function_type* oft = this->type_; + Typed_identifier* rec = new Typed_identifier(oft->receiver()->name(), + rtype, + oft->receiver()->location()); + Typed_identifier_list* parameters = NULL; + if (oft->parameters() != NULL) + parameters = oft->parameters()->copy(); + Typed_identifier_list* results = NULL; + if (oft->results() != NULL) + results = oft->results()->copy(); + Function_type* nft = Type::make_function_type(rec, parameters, results, + oft->location()); + this->type_ = nft; +} + // Swap one function with another. This is used when building the // thunk we use to call a function which calls recover. It may not // work for any other case. @@ -7285,6 +7305,26 @@ Function_declaration::set_nointerface() this->pragmas_ |= GOPRAGMA_NOINTERFACE; } +// Set the receiver type. This is used to remove aliases. + +void +Function_declaration::set_receiver_type(Type* rtype) +{ + Function_type* oft = this->fntype_; + Typed_identifier* rec = new Typed_identifier(oft->receiver()->name(), + rtype, + oft->receiver()->location()); + Typed_identifier_list* parameters = NULL; + if (oft->parameters() != NULL) + parameters = oft->parameters()->copy(); + Typed_identifier_list* results = NULL; + if (oft->results() != NULL) + results = oft->results()->copy(); + Function_type* nft = Type::make_function_type(rec, parameters, results, + oft->location()); + this->fntype_ = nft; +} + // Import an inlinable function. This is used for an inlinable // function whose body is recorded in the export data. Parse the // export data into a Block and create a regular function using that diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index f4155a29edb..c49bc92b3e0 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -1724,6 +1724,10 @@ class Function set_is_referenced_by_inline() { this->is_referenced_by_inline_ = true; } + // Set the receiver type. This is used to remove aliases. + void + set_receiver_type(Type* rtype); + // Swap with another function. Used only for the thunk which calls // recover. void @@ -1990,6 +1994,10 @@ class Function_declaration set_is_on_inlinable_list() { this->is_on_inlinable_list_ = true; } + // Set the receiver type. This is used to remove aliases. + void + set_receiver_type(Type* rtype); + // Import the function body, creating a function. void import_function_body(Gogo*, Named_object*); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index d08cbc96ea1..ab7166b8b1b 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -10416,6 +10416,57 @@ Named_type::finalize_methods(Gogo* gogo) return; } + // Remove any aliases in the local method receiver types. + Bindings* methods = this->local_methods_; + if (methods != NULL) + { + for (Bindings::const_declarations_iterator p = + methods->begin_declarations(); + p != methods->end_declarations(); + ++p) + { + Named_object* no = p->second; + Function_type* fntype; + if (no->is_function()) + fntype = no->func_value()->type(); + else if (no->is_function_declaration()) + fntype = no->func_declaration_value()->type(); + else + { + go_assert(saw_errors()); + continue; + } + + Type* rtype = fntype->receiver()->type(); + bool is_pointer = false; + Type* pt = rtype->points_to(); + if (pt != NULL) + { + rtype = pt; + is_pointer = true; + } + if (rtype->named_type() != this) + { + if (rtype->unalias() != this) + { + go_assert(saw_errors()); + continue; + } + + rtype = this; + if (is_pointer) + rtype = Type::make_pointer_type(rtype); + + if (no->is_function()) + no->func_value()->set_receiver_type(rtype); + else if (no->is_function_declaration()) + no->func_declaration_value()->set_receiver_type(rtype); + else + go_unreachable(); + } + } + } + Type::finalize_methods(gogo, this, this->location_, &this->all_methods_); }