From patchwork Tue Jul 6 19:21:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 58056 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 A5B24B6EEF for ; Wed, 7 Jul 2010 05:21:33 +1000 (EST) Received: (qmail 2529 invoked by alias); 6 Jul 2010 19:21:31 -0000 Received: (qmail 2521 invoked by uid 22791); 6 Jul 2010 19:21:30 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 06 Jul 2010 19:21:21 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o66JLJZA032150 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 6 Jul 2010 15:21:20 -0400 Received: from [IPv6:::1] (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o66JLJYw027221 for ; Tue, 6 Jul 2010 15:21:19 -0400 Message-ID: <4C33822E.7060004@redhat.com> Date: Tue, 06 Jul 2010 15:21:18 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.10) Gecko/20100619 Lightning/1.0b1 Shredder/3.0.6pre MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/44778 (4.6 ptrmem regression) 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 Some fallout from the dependent_scope_ref_p change; now that we can get a non-dependent SCOPE_REF in build_offset_ref, we need to handle it properly. In this case the qualified-id is not dependent, but when we take its address we get a type-dependent pointer to member. Tested x86_64-pc-linux-gnu, applied to trunk. commit 9b53d24ba67dae7b803edbb8d2e46e2600cb41fb Author: Jason Merrill Date: Fri Jul 2 23:48:32 2010 -0400 PR c++/44778 * init.c (build_offset_ref): If scope isn't dependent, don't exit early. Look at TYPE_MAIN_VARIANT. * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ec7dca9..20f921d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1507,18 +1507,9 @@ build_offset_ref (tree type, tree member, bool address_p) if (TREE_CODE (member) == TEMPLATE_DECL) return member; - if (dependent_type_p (type) || type_dependent_expression_p (member)) - { - tree ref, mem_type = NULL_TREE; - if (!dependent_scope_p (type)) - mem_type = TREE_TYPE (member); - ref = build_qualified_name (mem_type, type, member, + if (dependent_scope_p (type) || type_dependent_expression_p (member)) + return build_qualified_name (NULL_TREE, type, member, /*template_p=*/false); - /* Undo convert_from_reference. */ - if (TREE_CODE (ref) == INDIRECT_REF) - ref = TREE_OPERAND (ref, 0); - return ref; - } gcc_assert (TYPE_P (type)); if (! is_class_type (type, 1)) @@ -1528,6 +1519,7 @@ build_offset_ref (tree type, tree member, bool address_p) /* Callers should call mark_used before this point. */ gcc_assert (!DECL_P (member) || TREE_USED (member)); + type = TYPE_MAIN_VARIANT (type); if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type))) { error ("incomplete type %qT does not have member %qD", type, member); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f542b21..80cf7d2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11309,8 +11309,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_unreachable (); case OFFSET_REF: - mark_used (TREE_OPERAND (t, 1)); - return t; + r = build2 + (code, tsubst (TREE_TYPE (t), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + PTRMEM_OK_P (r) = PTRMEM_OK_P (t); + mark_used (TREE_OPERAND (r, 1)); + return r; case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); diff --git a/gcc/testsuite/g++.dg/template/ptrmem17.C b/gcc/testsuite/g++.dg/template/ptrmem17.C index a79e3c8..5c5ee3f 100644 --- a/gcc/testsuite/g++.dg/template/ptrmem17.C +++ b/gcc/testsuite/g++.dg/template/ptrmem17.C @@ -7,4 +7,4 @@ template struct A ~A() { &A::i; } // { dg-error "reference" } }; -A<0> a; // { dg-message "instantiated" } +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/ptrmem22.C b/gcc/testsuite/g++.dg/template/ptrmem22.C new file mode 100644 index 0000000..762f377 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem22.C @@ -0,0 +1,29 @@ +// PR c++/44778 + +enum Healpix_Ordering_Scheme { RING, NEST }; + +class Healpix_Base + { + protected: + Healpix_Ordering_Scheme scheme_; + int nest2ring (int pix) const; + int ring2nest (int pix) const; + + typedef int (Healpix_Base::*swapfunc)(int pix) const; + }; + +template class Healpix_Map: public Healpix_Base + { + public: + void Import_nograde (const Healpix_Map &orig) + { + swapfunc swapper = (scheme_ == NEST) ? + &Healpix_Map::ring2nest : &Healpix_Map::nest2ring; + } + }; + +int main() + { + Healpix_Map a,b; + a.Import_nograde(b); + }