Commit 5cc2edcd by Jason Merrill Committed by Jason Merrill

re PR c++/59044 (Internal compiler error triggers when accessing a typedef in a…

re PR c++/59044 (Internal compiler error triggers when accessing a typedef in a specialized member class)

	PR c++/59044
	PR c++/59052
	* pt.c (most_specialized_class): Use the partially instantiated
	template for deduction.  Drop the TMPL parameter.

From-SVN: r205720
parent a8f014d7
2013-12-05 Jason Merrill <jason@redhat.com>
PR c++/59044
PR c++/59052
* pt.c (most_specialized_class): Use the partially instantiated
template for deduction. Drop the TMPL parameter.
2013-12-05 Paolo Carlini <paolo.carlini@oracle.com> 2013-12-05 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (duplicate_decls): Replace pairs of errors and permerrors * decl.c (duplicate_decls): Replace pairs of errors and permerrors
......
...@@ -176,7 +176,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); ...@@ -176,7 +176,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
static void regenerate_decl_from_template (tree, tree); static void regenerate_decl_from_template (tree, tree);
static tree most_specialized_class (tree, tree, tsubst_flags_t); static tree most_specialized_class (tree, tsubst_flags_t);
static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
...@@ -4305,7 +4305,7 @@ process_partial_specialization (tree decl) ...@@ -4305,7 +4305,7 @@ process_partial_specialization (tree decl)
if (COMPLETE_TYPE_P (inst_type) if (COMPLETE_TYPE_P (inst_type)
&& CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type))
{ {
tree spec = most_specialized_class (inst_type, maintmpl, tf_none); tree spec = most_specialized_class (inst_type, tf_none);
if (spec && TREE_TYPE (spec) == type) if (spec && TREE_TYPE (spec) == type)
permerror (input_location, permerror (input_location,
"partial specialization of %qT after instantiation " "partial specialization of %qT after instantiation "
...@@ -8716,7 +8716,7 @@ instantiate_class_template_1 (tree type) ...@@ -8716,7 +8716,7 @@ instantiate_class_template_1 (tree type)
/* Determine what specialization of the original template to /* Determine what specialization of the original template to
instantiate. */ instantiate. */
t = most_specialized_class (type, templ, tf_warning_or_error); t = most_specialized_class (type, tf_warning_or_error);
if (t == error_mark_node) if (t == error_mark_node)
{ {
TYPE_BEING_DEFINED (type) = 1; TYPE_BEING_DEFINED (type) = 1;
...@@ -18242,7 +18242,7 @@ more_specialized_fn (tree pat1, tree pat2, int len) ...@@ -18242,7 +18242,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
return -1; return -1;
} }
/* Determine which of two partial specializations of MAIN_TMPL is more /* Determine which of two partial specializations of TMPL is more
specialized. specialized.
PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
...@@ -18258,7 +18258,7 @@ more_specialized_fn (tree pat1, tree pat2, int len) ...@@ -18258,7 +18258,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
two templates is more specialized. */ two templates is more specialized. */
static int static int
more_specialized_class (tree main_tmpl, tree pat1, tree pat2) more_specialized_class (tree tmpl, tree pat1, tree pat2)
{ {
tree targs; tree targs;
tree tmpl1, tmpl2; tree tmpl1, tmpl2;
...@@ -18273,7 +18273,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2) ...@@ -18273,7 +18273,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
types in the arguments, and we need our dependency check functions types in the arguments, and we need our dependency check functions
to behave correctly. */ to behave correctly. */
++processing_template_decl; ++processing_template_decl;
targs = get_class_bindings (main_tmpl, TREE_VALUE (pat1), targs = get_class_bindings (tmpl, TREE_VALUE (pat1),
CLASSTYPE_TI_ARGS (tmpl1), CLASSTYPE_TI_ARGS (tmpl1),
CLASSTYPE_TI_ARGS (tmpl2)); CLASSTYPE_TI_ARGS (tmpl2));
if (targs) if (targs)
...@@ -18282,7 +18282,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2) ...@@ -18282,7 +18282,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
any_deductions = true; any_deductions = true;
} }
targs = get_class_bindings (main_tmpl, TREE_VALUE (pat2), targs = get_class_bindings (tmpl, TREE_VALUE (pat2),
CLASSTYPE_TI_ARGS (tmpl2), CLASSTYPE_TI_ARGS (tmpl2),
CLASSTYPE_TI_ARGS (tmpl1)); CLASSTYPE_TI_ARGS (tmpl1));
if (targs) if (targs)
...@@ -18363,7 +18363,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) ...@@ -18363,7 +18363,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
} }
/* Return the innermost template arguments that, when applied to a partial /* Return the innermost template arguments that, when applied to a partial
specialization of MAIN_TMPL whose innermost template parameters are specialization of TMPL whose innermost template parameters are
TPARMS, and whose specialization arguments are SPEC_ARGS, yield the TPARMS, and whose specialization arguments are SPEC_ARGS, yield the
ARGS. ARGS.
...@@ -18378,7 +18378,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) ...@@ -18378,7 +18378,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
is bound to `double'. */ is bound to `double'. */
static tree static tree
get_class_bindings (tree main_tmpl, tree tparms, tree spec_args, tree args) get_class_bindings (tree tmpl, tree tparms, tree spec_args, tree args)
{ {
int i, ntparms = TREE_VEC_LENGTH (tparms); int i, ntparms = TREE_VEC_LENGTH (tparms);
tree deduced_args; tree deduced_args;
...@@ -18418,8 +18418,8 @@ get_class_bindings (tree main_tmpl, tree tparms, tree spec_args, tree args) ...@@ -18418,8 +18418,8 @@ get_class_bindings (tree main_tmpl, tree tparms, tree spec_args, tree args)
`T' is `A' but unify () does not check whether `typename T::X' `T' is `A' but unify () does not check whether `typename T::X'
is `int'. */ is `int'. */
spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE); spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (main_tmpl), spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
spec_args, main_tmpl, spec_args, tmpl,
tf_none, false, false); tf_none, false, false);
if (spec_args == error_mark_node if (spec_args == error_mark_node
/* We only need to check the innermost arguments; the other /* We only need to check the innermost arguments; the other
...@@ -18567,30 +18567,30 @@ most_general_template (tree decl) ...@@ -18567,30 +18567,30 @@ most_general_template (tree decl)
} }
/* Return the most specialized of the class template partial /* Return the most specialized of the class template partial
specializations of TMPL which can produce TYPE, a specialization of specializations which can produce TYPE, a specialization of some class
TMPL. The value returned is actually a TREE_LIST; the TREE_TYPE is template. The value returned is actually a TREE_LIST; the TREE_TYPE is
a _TYPE node corresponding to the partial specialization, while the a _TYPE node corresponding to the partial specialization, while the
TREE_PURPOSE is the set of template arguments that must be TREE_PURPOSE is the set of template arguments that must be
substituted into the TREE_TYPE in order to generate TYPE. substituted into the TREE_TYPE in order to generate TYPE.
If the choice of partial specialization is ambiguous, a diagnostic If the choice of partial specialization is ambiguous, a diagnostic
is issued, and the error_mark_node is returned. If there are no is issued, and the error_mark_node is returned. If there are no
partial specializations of TMPL matching TYPE, then NULL_TREE is partial specializations matching TYPE, then NULL_TREE is
returned. */ returned, indicating that the primary template should be used. */
static tree static tree
most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) most_specialized_class (tree type, tsubst_flags_t complain)
{ {
tree list = NULL_TREE; tree list = NULL_TREE;
tree t; tree t;
tree champ; tree champ;
int fate; int fate;
bool ambiguous_p; bool ambiguous_p;
tree args;
tree outer_args = NULL_TREE; tree outer_args = NULL_TREE;
tmpl = most_general_template (tmpl); tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
args = CLASSTYPE_TI_ARGS (type); tree main_tmpl = most_general_template (tmpl);
tree args = CLASSTYPE_TI_ARGS (type);
/* For determining which partial specialization to use, only the /* For determining which partial specialization to use, only the
innermost args are interesting. */ innermost args are interesting. */
...@@ -18600,7 +18600,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) ...@@ -18600,7 +18600,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
args = INNERMOST_TEMPLATE_ARGS (args); args = INNERMOST_TEMPLATE_ARGS (args);
} }
for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t)) for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t))
{ {
tree partial_spec_args; tree partial_spec_args;
tree spec_args; tree spec_args;
...@@ -18625,8 +18625,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) ...@@ -18625,8 +18625,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
partial_spec_args = partial_spec_args =
coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
add_to_template_args (outer_args, partial_spec_args,
partial_spec_args),
tmpl, tf_none, tmpl, tf_none,
/*require_all_args=*/true, /*require_all_args=*/true,
/*use_default_args=*/true); /*use_default_args=*/true);
......
// PR c++/59044
template <class T>
class C {
private:
template <T a, T b>
struct Implementation {};
public:
typedef typename Implementation<0, 0>::Typedef Type;
};
template <class T>
template <T b>
struct C<T>::Implementation<0, b> { typedef void Typedef; };
template class C<unsigned>;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment