re PR c++/8389 (Access to members of base class & templates)

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.

	PR c++/8389
	* g++.dg/template/access6.C: New test.

From-SVN: r58950
This commit is contained in:
Kriang Lerdsuwanakij 2002-11-09 11:53:18 +00:00 committed by Kriang Lerdsuwanakij
parent 8a9a176bf6
commit 5c74d5b03c
6 changed files with 58 additions and 21 deletions

View File

@ -1,3 +1,13 @@
2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
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-07 Mark Mitchell <mark@codesourcery.com>
* class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of

View File

@ -4013,7 +4013,7 @@ extern void print_candidates PARAMS ((tree));
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 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));

View File

@ -656,7 +656,7 @@ write_encoding (decl)
tree fn_type;
if (decl_is_template_id (decl, NULL))
fn_type = get_mostly_instantiated_function_type (decl, NULL, NULL);
fn_type = get_mostly_instantiated_function_type (decl);
else
fn_type = TREE_TYPE (decl);
@ -1011,8 +1011,7 @@ write_unqualified_name (decl)
tree type;
if (decl_is_template_id (decl, NULL))
{
tree fn_type = get_mostly_instantiated_function_type (decl, NULL,
NULL);
tree fn_type = get_mostly_instantiated_function_type (decl);
type = TREE_TYPE (fn_type);
}
else

View File

@ -7786,9 +7786,19 @@ instantiate_template (tmpl, targ_ptr)
}
}
/* 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;
@ -10414,18 +10424,12 @@ tsubst_enum (tag, newtag, args)
/* 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. */
the type. */
tree
get_mostly_instantiated_function_type (decl, contextp, tparmsp)
get_mostly_instantiated_function_type (decl)
tree decl;
tree *contextp;
tree *tparmsp;
{
tree context = NULL_TREE;
tree fn_type;
tree tmpl;
tree targs;
@ -10442,8 +10446,6 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
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. */
@ -10463,11 +10465,17 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
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);
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
@ -10475,12 +10483,10 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
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;
if (DECL_CLASS_SCOPE_P (decl))
popclass ();
}
return fn_type;
}

View File

@ -1,3 +1,8 @@
2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/8389
* g++.dg/template/access6.C: New test.
Fri Nov 8 10:52:15 CET 2002 Jan Hubicka <jh@suse.cz>
* gcc.c-torture/compile/20021108-1.c: New testcase for x86-64 failure.

View File

@ -0,0 +1,17 @@
// { dg-do compile }
// Origin: Detlef Vollmann <dv@vollmann.ch>
// PR c++/8389
// Access control ICE for typename during instantiation and name mangling
template <class> class Base {
protected:
typedef int Type;
};
template <class T> struct Derived : public Base<T> {
typedef typename Base<T>::Type Type;
template <class Arg> void f(Type = Type()) {};
};
template void Derived<char>::f<int> (Type);