diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-06-16 06:08:49 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-06-16 06:08:49 +0000 |
commit | 4e95268d59d17d5d58d60f2067a79a215d65db73 (patch) | |
tree | 2cd5e1744fea5e85f23366a250ecce719577ca85 /gcc | |
parent | 2954333afc6cbb12f5628368b5f557a5730d1242 (diff) | |
download | gcc-4e95268d59d17d5d58d60f2067a79a215d65db73.zip gcc-4e95268d59d17d5d58d60f2067a79a215d65db73.tar.gz gcc-4e95268d59d17d5d58d60f2067a79a215d65db73.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 76 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp18.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp19.C | 7 |
6 files changed, 77 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 778658af..bb1ea7f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c0897a0..e9f28a6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d25ea79..79183f5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0696d9a..313a39f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 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. diff --git a/gcc/testsuite/g++.dg/template/ttp18.C b/gcc/testsuite/g++.dg/template/ttp18.C new file mode 100644 index 0000000..095c07f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp18.C @@ -0,0 +1,10 @@ +template <template <typename> class T> +void f(T<int>) {} + +template <typename T> +union U {}; + +void g() { + f(U<int>()); +} + diff --git a/gcc/testsuite/g++.dg/template/ttp19.C b/gcc/testsuite/g++.dg/template/ttp19.C new file mode 100644 index 0000000..12a37c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp19.C @@ -0,0 +1,7 @@ +// 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); } + |