From patchwork Fri Jan 27 23:19:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 138365 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 94D0BB6F68 for ; Sat, 28 Jan 2012 10:20:17 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1328311218; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Cc:Subject:References:Date:In-Reply-To: Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=mrHzZGxpR15cT27HrNVbU+yfPsQ=; b=n5uGWP24gIIheyPv+rS36JKPzFhgQ0TA3KE88lQzNb7BMtNVlZDsBylOynzKc5 SxIkMMFK9jKwm6eZkMz657FxAjcMEi3exA5iT7OZ0ETYDbKeSraJX+wK1+lJcMzC Q1Ru+0W9ySafgTl9X4fd7qO18Sl14T88kEteTIwg2eKek= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Cc:Subject:References:X-URL:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=L5DeH+I3N8Iblb6JN7e1CDk2gE/lMhWu7CwTnEzsUzLKN8tTUei4f5X+S+2oJG SOMX8ncPoJq48PswMoCUXSzLEHHzO6+zK3pwP8jzh7aL3lh7wNgjPTGTlS+VGrDI 1yrbqhrkrsGproMcZhPW0zG1sOEP9sOmZghITQDW5L+uk=; Received: (qmail 22691 invoked by alias); 27 Jan 2012 23:20:13 -0000 Received: (qmail 22668 invoked by uid 22791); 27 Jan 2012 23:20:11 -0000 X-SWARE-Spam-Status: No, hits=-6.2 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; Fri, 27 Jan 2012 23:19:53 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q0RNJr9B022337 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 27 Jan 2012 18:19:53 -0500 Received: from localhost (ovpn-116-32.ams2.redhat.com [10.36.116.32]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q0RNJp4A018369 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 27 Jan 2012 18:19:52 -0500 Received: by localhost (Postfix, from userid 500) id D5EC029C0E1; Sat, 28 Jan 2012 00:19:50 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: Re: [PATCH] PR c++/51641 - Lookup finds enclosing class member instead of template parameter References: <4F21D00F.6080301@redhat.com> X-URL: http://www.redhat.com Date: Sat, 28 Jan 2012 00:19:50 +0100 In-Reply-To: <4F21D00F.6080301@redhat.com> (Jason Merrill's message of "Thu, 26 Jan 2012 17:13:35 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 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 Jason Merrill writes: > Comparing by same_type_p means that we treat any template parameter of > the appropriate level and index as equivalent. But that should be OK, > since we only have one set of level N template parameters in scope. > So I think we should be able to just compare the level of the template > parameter to the level of the parameters of the template. Right? OK. I understand that just comparing levels like that is not a good enough implementation for parameter_of_template_p in the general case. So I removed that function and did the test inline in binding_to_template_parms_of_scope_p instead. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. gcc/cp/ PR c++/51641 * cp-tree.h (template_type_parameter_p): Declare new function. (parameter_of_template_p): Remove * pt.c (template_type_parameter_p): Define new function. (parameter_of_template_p): Remove. * name-lookup.c (binding_to_template_parms_of_scope_p): Don't rely on parameter_of_template_p anymore. Compare the level of the template parameter to the depth of the template. gcc/testsuite/ PR c++/51641 * g++.dg/lookup/hidden-class17.C: New test. --- gcc/cp/cp-tree.h | 2 +- gcc/cp/name-lookup.c | 36 ++++++++++++++++----- gcc/cp/pt.c | 44 +++++++------------------- gcc/testsuite/g++.dg/lookup/hidden-class17.C | 22 +++++++++++++ 4 files changed, 62 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-class17.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f27755e..71bca53 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5357,10 +5357,10 @@ extern bool explicit_class_specialization_p (tree); extern int push_tinst_level (tree); extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); -extern bool parameter_of_template_p (tree, tree); extern void init_template_processing (void); extern void print_template_statistics (void); bool template_template_parameter_p (const_tree); +bool template_type_parameter_p (const_tree); extern bool primary_template_instantiation_p (const_tree); extern tree get_primary_template_innermost_parameters (const_tree); extern tree get_template_parms_at_level (tree, int); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 2351342..3330138 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4466,21 +4466,39 @@ static bool binding_to_template_parms_of_scope_p (cxx_binding *binding, cp_binding_level *scope) { - tree binding_value; + tree binding_value, tmpl; + int level; if (!binding || !scope) return false; binding_value = binding->value ? binding->value : binding->type; + /* BINDING_VALUE must be a template parm. */ + if (binding_value == NULL_TREE + && (!DECL_P (binding_value) + || !DECL_TEMPLATE_PARM_P (binding_value))) + return false; - return (scope - && scope->this_entity - && get_template_info (scope->this_entity) - && PRIMARY_TEMPLATE_P (TI_TEMPLATE - (get_template_info (scope->this_entity))) - && parameter_of_template_p (binding_value, - TI_TEMPLATE (get_template_info \ - (scope->this_entity)))); + /* The level of BINDING_VALUE. */ + level = + template_type_parameter_p (binding_value) + ? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX + (TREE_TYPE (binding_value))) + : TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value)); + + /* The template of the current scope, iff said scope is a primary + template. */ + tmpl = + (scope + && scope->this_entity + && get_template_info (scope->this_entity) + && PRIMARY_TEMPLATE_P (TI_TEMPLATE (get_template_info (scope->this_entity)))) + ? TI_TEMPLATE (get_template_info (scope->this_entity)) + : NULL_TREE; + + /* If the level of the parm BINDING_VALUE equals the depth of TMPL, + then BINDING_VALUE is a parameter of TMPL. */ + return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); } /* Return the innermost non-namespace binding for NAME from a scope diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e440be7..76d09aa 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2890,6 +2890,18 @@ template_template_parameter_p (const_tree parm) return DECL_TEMPLATE_TEMPLATE_PARM_P (parm); } +/* Return true iff PARM is a DECL representing a type template + parameter. */ + +bool +template_type_parameter_p (const_tree parm) +{ + return (parm + && (TREE_CODE (parm) == TYPE_DECL + || TREE_CODE (parm) == TEMPLATE_DECL) + && DECL_TEMPLATE_PARM_P (parm)); +} + /* Return the template parameters of T if T is a primary template instantiation, NULL otherwise. */ @@ -8137,38 +8149,6 @@ outermost_tinst_level (void) return level; } -/* Returns TRUE if PARM is a parameter of the template TEMPL. */ - -bool -parameter_of_template_p (tree parm, tree templ) -{ - tree parms; - int i; - - if (!parm || !templ) - return false; - - gcc_assert (DECL_TEMPLATE_PARM_P (parm)); - gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); - - parms = DECL_TEMPLATE_PARMS (templ); - parms = INNERMOST_TEMPLATE_PARMS (parms); - - for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) - { - tree p = TREE_VALUE (TREE_VEC_ELT (parms, i)); - if (p == error_mark_node) - continue; - - if (parm == p - || (DECL_INITIAL (parm) - && DECL_INITIAL (parm) == DECL_INITIAL (p))) - return true; - } - - return false; -} - /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class17.C b/gcc/testsuite/g++.dg/lookup/hidden-class17.C new file mode 100644 index 0000000..3d5ccec --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-class17.C @@ -0,0 +1,22 @@ +// Origin PR c++/51641 +// { dg-do compile } + +struct A { + struct B { typedef int X; }; +}; + +template struct C : A { + B::X q; // Ok: A::B. + struct U { typedef int X; }; + template + struct D; +}; + +template +template +struct C::D { + typename U::X r; // { dg-error "" } +}; + +C::D y; +