mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
re PR c++/26988 (template constructor in template class derived from virtual base can not be specialized)
PR c++/26988 * pt.c (determine_specialization): Use skip_artificial_parms_for. (fn_type_unificiation): Likewise. (get_bindings): Likewise. PR c++/26988 * g++.dg/template/spec34.C: New test From-SVN: r121826
This commit is contained in:
committed by
Mark Mitchell
parent
e4dcec70a5
commit
eedb0fab79
@@ -1,3 +1,10 @@
|
||||
2007-02-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/26988
|
||||
* pt.c (determine_specialization): Use skip_artificial_parms_for.
|
||||
(fn_type_unificiation): Likewise.
|
||||
(get_bindings): Likewise.
|
||||
|
||||
2007-02-06 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR target/29487
|
||||
|
||||
70
gcc/cp/pt.c
70
gcc/cp/pt.c
@@ -1429,33 +1429,6 @@ determine_specialization (tree template_id,
|
||||
tree decl_arg_types;
|
||||
tree fn_arg_types;
|
||||
|
||||
/* DECL might be a specialization of FN. */
|
||||
|
||||
/* Adjust the type of DECL in case FN is a static member. */
|
||||
decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
|
||||
if (DECL_STATIC_FUNCTION_P (fn)
|
||||
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
|
||||
decl_arg_types = TREE_CHAIN (decl_arg_types);
|
||||
|
||||
/* Check that the number of function parameters matches.
|
||||
For example,
|
||||
template <class T> void f(int i = 0);
|
||||
template <> void f<int>();
|
||||
The specialization f<int> is invalid but is not caught
|
||||
by get_bindings below. */
|
||||
|
||||
fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
if (list_length (fn_arg_types) != list_length (decl_arg_types))
|
||||
continue;
|
||||
|
||||
/* For a non-static member function, we need to make sure that
|
||||
the const qualification is the same. This can be done by
|
||||
checking the 'this' in the argument list. */
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
|
||||
&& !same_type_p (TREE_VALUE (fn_arg_types),
|
||||
TREE_VALUE (decl_arg_types)))
|
||||
continue;
|
||||
|
||||
/* In case of explicit specialization, we need to check if
|
||||
the number of template headers appearing in the specialization
|
||||
is correct. This is usually done in check_explicit_specialization,
|
||||
@@ -1494,14 +1467,44 @@ determine_specialization (tree template_id,
|
||||
(current_template_parms))))
|
||||
continue;
|
||||
|
||||
/* DECL might be a specialization of FN. */
|
||||
decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
|
||||
fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
|
||||
/* For a non-static member function, we need to make sure
|
||||
that the const qualification is the same. Since
|
||||
get_bindings does not try to merge the "this" parameter,
|
||||
we must do the comparison explicitly. */
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
|
||||
&& !same_type_p (TREE_VALUE (fn_arg_types),
|
||||
TREE_VALUE (decl_arg_types)))
|
||||
continue;
|
||||
|
||||
/* Skip the "this" parameter and, for constructors of
|
||||
classes with virtual bases, the VTT parameter. A
|
||||
full specialization of a constructor will have a VTT
|
||||
parameter, but a template never will. */
|
||||
decl_arg_types
|
||||
= skip_artificial_parms_for (decl, decl_arg_types);
|
||||
fn_arg_types
|
||||
= skip_artificial_parms_for (fn, fn_arg_types);
|
||||
|
||||
/* Check that the number of function parameters matches.
|
||||
For example,
|
||||
template <class T> void f(int i = 0);
|
||||
template <> void f<int>();
|
||||
The specialization f<int> is invalid but is not caught
|
||||
by get_bindings below. */
|
||||
if (list_length (fn_arg_types) != list_length (decl_arg_types))
|
||||
continue;
|
||||
|
||||
/* Function templates cannot be specializations; there are
|
||||
no partial specializations of functions. Therefore, if
|
||||
the type of DECL does not match FN, there is no
|
||||
match. */
|
||||
if (tsk == tsk_template)
|
||||
{
|
||||
if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
|
||||
decl_arg_types))
|
||||
if (compparms (fn_arg_types, decl_arg_types))
|
||||
candidates = tree_cons (NULL_TREE, fn, candidates);
|
||||
continue;
|
||||
}
|
||||
@@ -9728,10 +9731,8 @@ fn_type_unification (tree fn,
|
||||
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
|
||||
}
|
||||
|
||||
parms = TYPE_ARG_TYPES (fntype);
|
||||
/* Never do unification on the 'this' parameter. */
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
|
||||
parms = TREE_CHAIN (parms);
|
||||
parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype));
|
||||
|
||||
if (return_type)
|
||||
{
|
||||
@@ -11279,10 +11280,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
decl_arg_types = TYPE_ARG_TYPES (decl_type);
|
||||
/* Never do unification on the 'this' parameter. */
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
|
||||
decl_arg_types = TREE_CHAIN (decl_arg_types);
|
||||
decl_arg_types = skip_artificial_parms_for (decl,
|
||||
TYPE_ARG_TYPES (decl_type));
|
||||
|
||||
if (fn_type_unification (fn, explicit_args, targs,
|
||||
decl_arg_types,
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2007-02-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/26988
|
||||
* g++.dg/template/spec34.C: New test
|
||||
|
||||
2007-02-10 Bernhard Fischer <aldot@gcc.gnu.org>
|
||||
|
||||
Backport from trunk:
|
||||
|
||||
9
gcc/testsuite/g++.dg/template/spec34.C
Normal file
9
gcc/testsuite/g++.dg/template/spec34.C
Normal file
@@ -0,0 +1,9 @@
|
||||
// PR c++/26988
|
||||
|
||||
struct B{};
|
||||
|
||||
struct Bar : virtual B {
|
||||
template <typename T> Bar( T const& cast );
|
||||
};
|
||||
|
||||
template <> Bar::Bar( int const & cast ) {}
|
||||
Reference in New Issue
Block a user