summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-05 22:46:36 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-05 22:46:36 +0000
commit85fc67dcdaf98c6253ddec94fd5173429659c7f9 (patch)
tree2e6f1048e5e07bc60c989822895505594ae5bf16 /gcc
parentffc1a52f35789851feb0df8021f395bed2e768bb (diff)
downloadgcc-85fc67dcdaf98c6253ddec94fd5173429659c7f9.tar.gz
PR c++/59044
PR c++/59052 * pt.c (most_specialized_class): Use the partially instantiated template for deduction. Drop the TMPL parameter. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205720 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c43
-rw-r--r--gcc/testsuite/g++.dg/template/partial14.C16
3 files changed, 44 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2d5617a35cc..16b6aa00240 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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>
* decl.c (duplicate_decls): Replace pairs of errors and permerrors
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 25d940c695a..01b2d44ee8e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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_parms (tree, tree, tsubst_flags_t);
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_arg_types (tree, 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)
if (COMPLETE_TYPE_P (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)
permerror (input_location,
"partial specialization of %qT after instantiation "
@@ -8716,7 +8716,7 @@ instantiate_class_template_1 (tree type)
/* Determine what specialization of the original template to
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)
{
TYPE_BEING_DEFINED (type) = 1;
@@ -18242,7 +18242,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
return -1;
}
-/* Determine which of two partial specializations of MAIN_TMPL is more
+/* Determine which of two partial specializations of TMPL is more
specialized.
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)
two templates is more specialized. */
static int
-more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
+more_specialized_class (tree tmpl, tree pat1, tree pat2)
{
tree targs;
tree tmpl1, tmpl2;
@@ -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
to behave correctly. */
++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 (tmpl2));
if (targs)
@@ -18282,7 +18282,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
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 (tmpl1));
if (targs)
@@ -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
- 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
ARGS.
@@ -18378,7 +18378,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
is bound to `double'. */
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);
tree deduced_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'
is `int'. */
spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
- spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (main_tmpl),
- spec_args, main_tmpl,
+ spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+ spec_args, tmpl,
tf_none, false, false);
if (spec_args == error_mark_node
/* We only need to check the innermost arguments; the other
@@ -18567,30 +18567,30 @@ most_general_template (tree decl)
}
/* Return the most specialized of the class template partial
- specializations of TMPL which can produce TYPE, a specialization of
- TMPL. The value returned is actually a TREE_LIST; the TREE_TYPE is
+ specializations which can produce TYPE, a specialization of some class
+ template. The value returned is actually a TREE_LIST; the TREE_TYPE is
a _TYPE node corresponding to the partial specialization, while the
TREE_PURPOSE is the set of template arguments that must be
substituted into the TREE_TYPE in order to generate TYPE.
If the choice of partial specialization is ambiguous, a diagnostic
is issued, and the error_mark_node is returned. If there are no
- partial specializations of TMPL matching TYPE, then NULL_TREE is
- returned. */
+ partial specializations matching TYPE, then NULL_TREE is
+ returned, indicating that the primary template should be used. */
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 t;
tree champ;
int fate;
bool ambiguous_p;
- tree args;
tree outer_args = NULL_TREE;
- tmpl = most_general_template (tmpl);
- args = CLASSTYPE_TI_ARGS (type);
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+ tree main_tmpl = most_general_template (tmpl);
+ tree args = CLASSTYPE_TI_ARGS (type);
/* For determining which partial specialization to use, only the
innermost args are interesting. */
@@ -18600,7 +18600,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
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 spec_args;
@@ -18625,8 +18625,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
partial_spec_args =
coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
- add_to_template_args (outer_args,
- partial_spec_args),
+ partial_spec_args,
tmpl, tf_none,
/*require_all_args=*/true,
/*use_default_args=*/true);
diff --git a/gcc/testsuite/g++.dg/template/partial14.C b/gcc/testsuite/g++.dg/template/partial14.C
new file mode 100644
index 00000000000..3870164f0ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial14.C
@@ -0,0 +1,16 @@
+// 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>;