Commit 04afbf1c by Dodji Seketeli Committed by Dodji Seketeli

re PR c++/42824 (c++ compilation complains about error: call of overloaded)

Fix PR c++/42824

gcc/cp/ChangeLog:
	PR c++/42824
	* pt.c (lookup_template_class): Better support of specialization
	of member of class template implicit instantiation.

gcc/testsuite/ChangeLog:
	PR c++/42824
	* g++.dg/template/memclass4.C: New test.

From-SVN: r156939
parent d6648997
2010-02-21 Dodji Seketeli <dodji@redhat.com>
PR c++/42824
* pt.c (lookup_template_class): Better support of specialization
of member of class template implicit instantiation.
2010-02-20 Manuel López-Ibáñez <manu@gcc.gnu.org> 2010-02-20 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/35669 PR c++/35669
......
...@@ -6379,7 +6379,8 @@ lookup_template_class (tree d1, ...@@ -6379,7 +6379,8 @@ lookup_template_class (tree d1,
tree found = NULL_TREE; tree found = NULL_TREE;
int arg_depth; int arg_depth;
int parm_depth; int parm_depth;
int is_partial_instantiation; int is_dependent_type;
int use_partial_inst_tmpl = false;
gen_tmpl = most_general_template (templ); gen_tmpl = most_general_template (templ);
parmlist = DECL_TEMPLATE_PARMS (gen_tmpl); parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
...@@ -6495,21 +6496,17 @@ lookup_template_class (tree d1, ...@@ -6495,21 +6496,17 @@ lookup_template_class (tree d1,
if (entry) if (entry)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec);
/* This type is a "partial instantiation" if any of the template is_dependent_type = uses_template_parms (arglist);
arguments still involve template parameters. Note that we set
IS_PARTIAL_INSTANTIATION for partial specializations as
well. */
is_partial_instantiation = uses_template_parms (arglist);
/* If the deduced arguments are invalid, then the binding /* If the deduced arguments are invalid, then the binding
failed. */ failed. */
if (!is_partial_instantiation if (!is_dependent_type
&& check_instantiated_args (gen_tmpl, && check_instantiated_args (gen_tmpl,
INNERMOST_TEMPLATE_ARGS (arglist), INNERMOST_TEMPLATE_ARGS (arglist),
complain)) complain))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
if (!is_partial_instantiation if (!is_dependent_type
&& !PRIMARY_TEMPLATE_P (gen_tmpl) && !PRIMARY_TEMPLATE_P (gen_tmpl)
&& !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl)) && !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl))
&& TREE_CODE (CP_DECL_CONTEXT (gen_tmpl)) == NAMESPACE_DECL) && TREE_CODE (CP_DECL_CONTEXT (gen_tmpl)) == NAMESPACE_DECL)
...@@ -6528,7 +6525,7 @@ lookup_template_class (tree d1, ...@@ -6528,7 +6525,7 @@ lookup_template_class (tree d1,
/* Create the type. */ /* Create the type. */
if (TREE_CODE (template_type) == ENUMERAL_TYPE) if (TREE_CODE (template_type) == ENUMERAL_TYPE)
{ {
if (!is_partial_instantiation) if (!is_dependent_type)
{ {
set_current_access_from_decl (TYPE_NAME (template_type)); set_current_access_from_decl (TYPE_NAME (template_type));
t = start_enum (TYPE_IDENTIFIER (template_type), t = start_enum (TYPE_IDENTIFIER (template_type),
...@@ -6594,11 +6591,71 @@ lookup_template_class (tree d1, ...@@ -6594,11 +6591,71 @@ lookup_template_class (tree d1,
DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type); DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type);
} }
/* Set up the template information. We have to figure out which /* Let's consider the explicit specialization of a member
template is the immediate parent if this is a full of a class template specialization that is implicitely instantiated,
instantiation. */ e.g.:
if (parm_depth == 1 || is_partial_instantiation template<class T>
|| !PRIMARY_TEMPLATE_P (gen_tmpl)) struct S
{
template<class U> struct M {}; //#0
};
template<>
template<>
struct S<int>::M<char> //#1
{
int i;
};
[temp.expl.spec]/4 says this is valid.
In this case, when we write:
S<int>::M<char> m;
M is instantiated from the CLASSTYPE_TI_TEMPLATE of #1, not from
the one of #0.
When we encounter #1, we want to store the partial instantiation
of M (template<class T> S<int>::M<T>) in it's CLASSTYPE_TI_TEMPLATE.
For all cases other than this "explicit specialization of member of a
class template", we just want to store the most general template into
the CLASSTYPE_TI_TEMPLATE of M.
This case of "explicit specialization of member of a class template"
only happens when:
1/ the enclosing class is an instantiation of, and therefore not
the same as, the context of the most general template, and
2/ we aren't looking at the partial instantiation itself, i.e.
the innermost arguments are not the same as the innermost parms of
the most general template.
So it's only when 1/ and 2/ happens that we want to use the partial
instantiation of the member template in lieu of its most general
template. */
if (PRIMARY_TEMPLATE_P (gen_tmpl)
&& TMPL_ARGS_HAVE_MULTIPLE_LEVELS (arglist)
/* the enclosing class must be an instantiation... */
&& CLASS_TYPE_P (context)
&& !same_type_p (context, DECL_CONTEXT (gen_tmpl)))
{
tree partial_inst_args;
TREE_VEC_LENGTH (arglist)--;
++processing_template_decl;
partial_inst_args =
tsubst (INNERMOST_TEMPLATE_ARGS
(CLASSTYPE_TI_ARGS (TREE_TYPE (gen_tmpl))),
arglist, complain, NULL_TREE);
--processing_template_decl;
TREE_VEC_LENGTH (arglist)++;
use_partial_inst_tmpl =
/*...and we must not be looking at the partial instantiation
itself. */
!comp_template_args (INNERMOST_TEMPLATE_ARGS (arglist),
partial_inst_args);
}
if (!use_partial_inst_tmpl)
/* This case is easy; there are no member templates involved. */ /* This case is easy; there are no member templates involved. */
found = gen_tmpl; found = gen_tmpl;
else else
...@@ -6628,8 +6685,7 @@ lookup_template_class (tree d1, ...@@ -6628,8 +6685,7 @@ lookup_template_class (tree d1,
= tree_cons (arglist, t, = tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (templ)); DECL_TEMPLATE_INSTANTIATIONS (templ));
if (TREE_CODE (t) == ENUMERAL_TYPE if (TREE_CODE (t) == ENUMERAL_TYPE && !is_dependent_type)
&& !is_partial_instantiation)
/* Now that the type has been registered on the instantiations /* Now that the type has been registered on the instantiations
list, we set up the enumerators. Because the enumeration list, we set up the enumerators. Because the enumeration
constants may involve the enumeration type itself, we make constants may involve the enumeration type itself, we make
...@@ -6639,7 +6695,7 @@ lookup_template_class (tree d1, ...@@ -6639,7 +6695,7 @@ lookup_template_class (tree d1,
the instantiation and exit above. */ the instantiation and exit above. */
tsubst_enum (template_type, t, arglist); tsubst_enum (template_type, t, arglist);
if (is_partial_instantiation) if (is_dependent_type)
/* If the type makes use of template parameters, the /* If the type makes use of template parameters, the
code that generates debugging information will crash. */ code that generates debugging information will crash. */
DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1; DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;
......
2010-02-21 Dodji Seketeli <dodji@redhat.com>
PR c++/42824
* g++.dg/template/memclass4.C: New test.
2010-02-21 Tobias Burnus <burnus@net-b.de> 2010-02-21 Tobias Burnus <burnus@net-b.de>
PR fortran/35259 PR fortran/35259
......
// Origin: PR c++/42824
// { dg-do compile }
template<int T>
class int_ {
};
template<int T, int T2>
class Unit {
public:
Unit(const Unit<T, T2>& other) {}
};
template<int T>
class Quan {
public:
Quan(void) {}
template<int T2>
Quan(double value, Unit<T, T2> unit) {}
};
typedef Quan<0> Scalar;
template<int T>
class hlp {
public:
typedef Quan<T> type;
};
class Mtrl {
public:
template<int T>
struct AssoType {
typedef typename hlp<T>::type type;
};
};
template<class T>
class Eval {
public:
Eval(const T& object){}
template<int V>
void eval() {
eval<V> (int_<0>());
}
private:
template<typename U> struct Wrap {};
template<int V, int V2>
void value(Wrap<Quan<V2> >) {}
template<int V>
void value(Wrap<Scalar>) {}
template<int V>
void eval(int_<0>) {
typedef typename T::template AssoType<V>::type Type;
value<V>(Wrap<Type>());
}
};
class Foo {
public:
static void eval(const Mtrl& mtrl) {
Eval<Mtrl> h(mtrl);
h.eval<0> ();
}
};
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