Commit 4e95268d by Mark Mitchell Committed by Mark Mitchell

re PR c++/27689 (function template incorrectly selected as candidate)

	PR c++/27689
	* cp-tree.h (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): New
	macro.
	* pt.c (unify): Use it.
	PR c++/27689
	* g++.dg/template/ttp18.C: New test.
	* g++.dg/template/ttp19.C: Likewise.

From-SVN: r114703
parent 2954333a
2006-06-15 Mark Mitchell <mark@codesourcery.com>
PR c++/27689
* cp-tree.h (CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): New
macro.
* pt.c (unify): Use it.
PR c++/27666
* call.c (build_conditional_expr): Robustify.
......
......@@ -1117,14 +1117,6 @@ struct lang_type GTY(())
#endif /* ENABLE_TREE_CHECKING */
/* Indicates whether or not (and how) a template was expanded for this class.
0=no information yet/non-template class
1=implicit template instantiation
2=explicit template specialization
3=explicit template instantiation */
#define CLASSTYPE_USE_TEMPLATE(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->use_template)
/* Fields used for storing information before the class is defined.
After the class is defined, these fields hold other information. */
......@@ -2096,15 +2088,15 @@ extern void decl_shadowed_for_var_insert (tree, tree);
(DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
TEMPLATE_DECL, the entity is a template specialization. In that
case, DECL_TEMPLATE_INFO is a TREE_LIST, whose TREE_PURPOSE is the
TEMPLATE_DECL of which this entity is a specialization. The TREE_
TREE_VALUE is the template arguments used to specialize the
template.
In general, DECL_TEMPLATE_INFO is non-NULL only if
DECL_USE_TEMPLATE is nonzero. However, for friends, we sometimes
have DECL_TEMPLATE_INFO even when DECL_USE_TEMPLATE is zero.
TEMPLATE_DECL, the entity is either a template specialization (if
DECL_USE_TEMPLATE is non-zero) or the abstract instance of the
template itself.
In either case, DECL_TEMPLATE_INFO is a TREE_LIST, whose
TREE_PURPOSE is the TEMPLATE_DECL of which this entity is a
specialization or abstract instance. The TREE_VALUE is the
template arguments used to specialize the template.
Consider:
template <typename T> struct S { friend void f(T) {} };
......@@ -2112,7 +2104,8 @@ extern void decl_shadowed_for_var_insert (tree, tree);
In this case, S<int>::f is, from the point of view of the compiler,
an instantiation of a template -- but, from the point of view of
the language, each instantiation of S results in a wholly unrelated
global function f. */
global function f. In this case, DECL_TEMPLATE_INFO for S<int>::f
will be non-NULL, but DECL_USE_TEMPLATE will be zero. */
#define DECL_TEMPLATE_INFO(NODE) \
(DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
->decl_flags.u.template_info)
......@@ -2240,6 +2233,16 @@ extern void decl_shadowed_for_var_insert (tree, tree);
are always the full set of arguments required to instantiate this
declaration from the most general template specialized here. */
#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE))
/* The TEMPLATE_DECL associated with NODE, a class type. Even if NODE
will be generated from a partial specialization, the TEMPLATE_DECL
referred to here will be the original template. For example,
given:
template <typename T> struct S {};
template <typename T> struct S<T*> {};
the CLASSTPYE_TI_TEMPLATE for S<int*> will be S, not the S<T*>. */
#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
......@@ -2252,7 +2255,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
(CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
: (TYPE))
/* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */
/* Like CLASS_TI_TEMPLATE, but also works for ENUMERAL_TYPEs. */
#define TYPE_TI_TEMPLATE(NODE) \
(TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
......@@ -2845,17 +2848,38 @@ extern void decl_shadowed_for_var_insert (tree, tree);
/* Returns nonzero if NODE is a primary template. */
#define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE))
/* Indicates whether or not (and how) a template was expanded for this
FUNCTION_DECL or VAR_DECL.
0=normal declaration, e.g. int min (int, int);
1=implicit template instantiation
2=explicit template specialization, e.g. int min<int> (int, int);
3=explicit template instantiation, e.g. template int min<int> (int, int);
/* Non-zero iff NODE is a specialization of a template. The value
indicates the type of specializations:
1=implicit instantiation
2=explicit specialization, e.g. int min<int> (int, int);
3=explicit instantiation, e.g. template int min<int> (int, int);
If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
Note that NODE will be marked as a specialization even if the
template it is instantiating is not a primary template. For
example, given:
template <typename T> struct O {
void f();
struct I {};
};
both O<int>::f and O<int>::I will be marked as instantiations.
If DECL_USE_TEMPLATE is non-zero, then DECL_TEMPLATE_INFO will also
be non-NULL. */
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
/* Like DECL_USE_TEMPLATE, but for class types. */
#define CLASSTYPE_USE_TEMPLATE(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->use_template)
/* True if NODE is a specialization of a primary template. */
#define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE) \
(CLASS_TYPE_P (NODE) \
&& CLASSTYPE_USE_TEMPLATE (NODE) \
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
(CLASSTYPE_USE_TEMPLATE (NODE) & 1)
......
......@@ -10166,7 +10166,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* ARG must be constructed from a template class or a template
template parameter. */
if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
&& (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg)))
&& !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
return 1;
{
......
2006-06-15 Mark Mitchell <mark@codesourcery.com>
PR c++/27689
* g++.dg/template/ttp18.C: New test.
* g++.dg/template/ttp19.C: Likewise.
PR c++/27666
* g++.dg/expr/cond9.C: New test.
template <template <typename> class T>
void f(T<int>) {}
template <typename T>
union U {};
void g() {
f(U<int>());
}
// PR c++/27689
void f (...);
template <template <typename> class F, typename T> void f (F<T>);
template <typename> struct foo { struct bar {}; };
void g (foo<int>::bar x) { f(x); }
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