From patchwork Wed Sep 8 18:11:41 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: 64190 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 98F6BB6ED0 for ; Thu, 9 Sep 2010 04:12:01 +1000 (EST) Received: (qmail 12832 invoked by alias); 8 Sep 2010 18:11:57 -0000 Received: (qmail 12820 invoked by uid 22791); 8 Sep 2010 18:11:56 -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; Wed, 08 Sep 2010 18:11:51 +0000 Received: from hpaq13.eem.corp.google.com (hpaq13.eem.corp.google.com [172.25.149.13]) by smtp-out.google.com with ESMTP id o88IBm1P029318 for ; Wed, 8 Sep 2010 11:11:49 -0700 Received: from pxi6 (pxi6.prod.google.com [10.243.27.6]) by hpaq13.eem.corp.google.com with ESMTP id o88IBEJY026578 for ; Wed, 8 Sep 2010 11:11:47 -0700 Received: by pxi6 with SMTP id 6so187135pxi.31 for ; Wed, 08 Sep 2010 11:11:47 -0700 (PDT) Received: by 10.142.78.11 with SMTP id a11mr203931wfb.146.1283969507090; Wed, 08 Sep 2010 11:11:47 -0700 (PDT) Received: from coign.google.com (dhcp-172-22-123-203.mtv.corp.google.com [172.22.123.203]) by mx.google.com with ESMTPS id q23sm299506wfc.6.2010.09.08.11.11.45 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 08 Sep 2010 11:11:46 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] More recursive type patches Date: Wed, 08 Sep 2010 11:11:41 -0700 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 Here are some more patches for recursive types in gccgo. For a recursive pointer or function type, the recursion just uses ptr_type_node. This patch checks for that when doing a pointer indirection or function call, and insert a cast as needed so that GENERIC/GIMPLE see the right type. This patch also makes sure that we do not record the recursively found ptr_type_node when handling a forwarding type. Committed to gccgo branch. Ian diff -r 0442a71e2d75 go/expressions.cc --- a/go/expressions.cc Tue Sep 07 17:12:33 2010 -0700 +++ b/go/expressions.cc Wed Sep 08 11:08:53 2010 -0700 @@ -4002,6 +4002,15 @@ expr); } + // If the type of EXPR is a recursive pointer type, then we + // need to insert a cast before indirecting. + if (TREE_TYPE(TREE_TYPE(expr)) == ptr_type_node) + { + Type* pt = this->expr_->type()->points_to(); + tree ind = pt->get_tree(context->gogo()); + expr = fold_convert_loc(loc, build_pointer_type(ind), expr); + } + return build_fold_indirect_ref_loc(loc, expr); } @@ -8382,6 +8391,16 @@ CALL_EXPR_STATIC_CHAIN(ret) = closure_tree; } + // If this is a recursive function type which returns itself, as in + // type F func() F + // we have used ptr_type_node for the return type. Add a cast here + // to the correct type. + if (TREE_TYPE(ret) == ptr_type_node) + { + tree t = this->type()->get_tree(gogo); + ret = fold_convert_loc(location, t, ret); + } + if (excess_type != NULL_TREE) { // Calling convert here can undo our excess precision change. diff -r 0442a71e2d75 go/types.cc --- a/go/types.cc Tue Sep 07 17:12:33 2010 -0700 +++ b/go/types.cc Wed Sep 08 11:08:53 2010 -0700 @@ -781,9 +781,19 @@ { if (this->tree_ == NULL) { - this->tree_ = this->do_get_tree(gogo); - go_preserve_from_gc(this->tree_); - } + tree t = this->do_get_tree(gogo); + + // For a recursive function or pointer type, we will temporarily + // return ptr_type_node during the recursion. We don't want to + // record that for a forwarding type, as it may confuse us + // later. + if (t == ptr_type_node && this->forward_declaration_type() != NULL) + return t; + + this->tree_ = t; + go_preserve_from_gc(t); + } + return this->tree_; }