From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18596 invoked by alias); 8 Nov 2002 09:01:17 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 18407 invoked from network); 8 Nov 2002 09:01:10 -0000 Received: from unknown (HELO mozart.inet.co.th) (203.150.14.100) by sources.redhat.com with SMTP; 8 Nov 2002 09:01:10 -0000 Received: from users.sf.net (IDENT:Z41K80LyhGkV4z9ApLLaFTW6wD+SADsy@TruPPP0D150.inet.co.th [203.151.127.150]) by mozart.inet.co.th (8.9.1a/8.9.0) with ESMTP id QAA32326 for ; Fri, 8 Nov 2002 16:01:05 +0700 (GMT+0700) Message-ID: <3DCB7E30.1060901@users.sf.net> Date: Fri, 08 Nov 2002 01:01:00 -0000 From: Kriang Lerdsuwanakij Reply-To: lerdsuwa@users.sourceforge.net User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20020826 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] Fix PR8389 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2002-11/txt/msg00551.txt.bz2 Hi The appended patch fixes PR 8389. This is a regression in the main trunk caused by the enforcement of typename access checking a couple months ago. There are a few missed cases. In particular, inside "instantiate_template" and "get_mostly_instantiated_function_type" functions, "current_class_type" is not properly set up when we are tsubst'ing member functions. This is fixed by the patch. The patch also simplify the function get_mostly_instantiated_function_type a bit. The CONTEXTP and TPARMSP parameters are never used by the callers so they are removed. Also, the tsubst call for the function context is not required. It's the same for a fully instantiated DECL (with N levels of template arguments), and a partially instantiated N-1 levels of arguments. Bootstrapped and tested on i686-pc-linux-gnu with no regressions. OK to commit to main trunk? --Kriang 2002-11-08 Kriang Lerdsuwanakij PR c++/8389 * pt.c (instantiate_template): Push class scope for member functions. (get_mostly_instantiated_function_type): Likewise. Don't call tsubst on context. Remove CONTEXTP and TPARMSP parameters. * cp-tree.h (get_mostly_instantiated_function_type): Adjust. * mangle.c (write_encoding, write_unqualified_name): Adjust. 2002-11-08 Kriang Lerdsuwanakij PR c++/8389 * g++.dg/template/access6.C: New test. diff -cprN gcc-main-save/gcc/cp/cp-tree.h gcc-main-new/gcc/cp/cp-tree.h *** gcc-main-save/gcc/cp/cp-tree.h Wed Oct 30 22:49:01 2002 --- gcc-main-new/gcc/cp/cp-tree.h Fri Nov 8 11:39:15 2002 *************** extern void print_candidates *** 4010,4016 **** extern int instantiate_pending_templates PARAMS ((void)); extern tree tsubst_default_argument PARAMS ((tree, tree, tree)); extern tree most_general_template PARAMS ((tree)); ! extern tree get_mostly_instantiated_function_type PARAMS ((tree, tree *, tree *)); extern int problematic_instantiation_changed PARAMS ((void)); extern void record_last_problematic_instantiation PARAMS ((void)); extern tree current_instantiation PARAMS ((void)); --- 4010,4016 ---- extern int instantiate_pending_templates PARAMS ((void)); extern tree tsubst_default_argument PARAMS ((tree, tree, tree)); extern tree most_general_template PARAMS ((tree)); ! extern tree get_mostly_instantiated_function_type PARAMS ((tree)); extern int problematic_instantiation_changed PARAMS ((void)); extern void record_last_problematic_instantiation PARAMS ((void)); extern tree current_instantiation PARAMS ((void)); diff -cprN gcc-main-save/gcc/cp/mangle.c gcc-main-new/gcc/cp/mangle.c *** gcc-main-save/gcc/cp/mangle.c Fri Oct 18 22:29:12 2002 --- gcc-main-new/gcc/cp/mangle.c Fri Nov 8 11:39:03 2002 *************** write_encoding (decl) *** 656,662 **** tree fn_type; if (decl_is_template_id (decl, NULL)) ! fn_type = get_mostly_instantiated_function_type (decl, NULL, NULL); else fn_type = TREE_TYPE (decl); --- 656,662 ---- tree fn_type; if (decl_is_template_id (decl, NULL)) ! fn_type = get_mostly_instantiated_function_type (decl); else fn_type = TREE_TYPE (decl); *************** write_unqualified_name (decl) *** 1011,1018 **** tree type; if (decl_is_template_id (decl, NULL)) { ! tree fn_type = get_mostly_instantiated_function_type (decl, NULL, ! NULL); type = TREE_TYPE (fn_type); } else --- 1011,1017 ---- tree type; if (decl_is_template_id (decl, NULL)) { ! tree fn_type = get_mostly_instantiated_function_type (decl); type = TREE_TYPE (fn_type); } else diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c *** gcc-main-save/gcc/cp/pt.c Wed Oct 30 22:49:01 2002 --- gcc-main-new/gcc/cp/pt.c Fri Nov 8 15:48:35 2002 *************** instantiate_template (tmpl, targ_ptr) *** 7756,7764 **** --- 7756,7774 ---- } } + /* Make sure that we can see identifiers, and compute access + correctly. */ + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + pushclass (tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, tf_error, + gen_tmpl), 1); + /* substitute template parameters */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, tf_error, gen_tmpl); + + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + popclass (); + /* The DECL_TI_TEMPLATE should always be the immediate parent template, not the most general template. */ DECL_TI_TEMPLATE (fndecl) = tmpl; *************** tsubst_enum (tag, newtag, args) *** 10384,10401 **** /* DECL is a FUNCTION_DECL that is a template specialization. Return its type -- but without substituting the innermost set of template arguments. So, innermost set of template parameters will appear in ! the type. If CONTEXTP is non-NULL, then the partially substituted ! DECL_CONTEXT (if any) will also be filled in. Similarly, TPARMSP ! will be filled in with the substituted template parameters, if it ! is non-NULL. */ tree ! get_mostly_instantiated_function_type (decl, contextp, tparmsp) tree decl; - tree *contextp; - tree *tparmsp; { - tree context = NULL_TREE; tree fn_type; tree tmpl; tree targs; --- 10394,10405 ---- /* DECL is a FUNCTION_DECL that is a template specialization. Return its type -- but without substituting the innermost set of template arguments. So, innermost set of template parameters will appear in ! the type. */ tree ! get_mostly_instantiated_function_type (decl) tree decl; { tree fn_type; tree tmpl; tree targs; *************** get_mostly_instantiated_function_type (d *** 10412,10419 **** my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0); fn_type = TREE_TYPE (tmpl); - if (DECL_STATIC_FUNCTION_P (decl)) - context = DECL_CONTEXT (decl); if (parm_depth == 1) /* No substitution is necessary. */ --- 10416,10421 ---- *************** get_mostly_instantiated_function_type (d *** 10433,10443 **** TMPL_ARGS_DEPTH (targs), make_tree_vec (DECL_NTPARMS (tmpl))); /* Now, do the (partial) substitution to figure out the appropriate function type. */ fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE); - if (DECL_STATIC_FUNCTION_P (decl)) - context = tsubst (context, partial_args, tf_error, NULL_TREE); /* Substitute into the template parameters to obtain the real innermost set of parameters. This step is important if the --- 10435,10451 ---- TMPL_ARGS_DEPTH (targs), make_tree_vec (DECL_NTPARMS (tmpl))); + /* Make sure that we can see identifiers, and compute access + correctly. We can just use the context of DECL for the + partial substitution here. It depends only on outer template + parameters, regardless of whether the innermost level is + specialized or not. */ + if (DECL_CLASS_SCOPE_P (decl)) + pushclass (DECL_CONTEXT (decl), 1); + /* Now, do the (partial) substitution to figure out the appropriate function type. */ fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE); /* Substitute into the template parameters to obtain the real innermost set of parameters. This step is important if the *************** get_mostly_instantiated_function_type (d *** 10445,10456 **** parameters whose types depend on outer template parameters. */ TREE_VEC_LENGTH (partial_args)--; tparms = tsubst_template_parms (tparms, partial_args, tf_error); - } ! if (contextp) ! *contextp = context; ! if (tparmsp) ! *tparmsp = tparms; return fn_type; } --- 10453,10462 ---- parameters whose types depend on outer template parameters. */ TREE_VEC_LENGTH (partial_args)--; tparms = tsubst_template_parms (tparms, partial_args, tf_error); ! if (DECL_CLASS_SCOPE_P (decl)) ! popclass (); ! } return fn_type; } diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/access6.C gcc-main-new/gcc/testsuite/g++.dg/template/access6.C *** gcc-main-save/gcc/testsuite/g++.dg/template/access6.C Thu Jan 1 07:00:00 1970 --- gcc-main-new/gcc/testsuite/g++.dg/template/access6.C Thu Nov 7 22:37:11 2002 *************** *** 0 **** --- 1,17 ---- + // { dg-do compile } + // Origin: Detlef Vollmann + + // PR c++/8389 + // Access control ICE for typename during instantiation and name mangling + + template class Base { + protected: + typedef int Type; + }; + + template struct Derived : public Base { + typedef typename Base::Type Type; + template void f(Type = Type()) {}; + }; + + template void Derived::f (Type);