diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-12-21 05:00:43 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-12-21 05:00:43 +0000 |
commit | 0b808489a2d152ccb85824e7bfd836a21342c021 (patch) | |
tree | 85ffa26ec5a0fbc5e4e768b3e229b898960bb08f | |
parent | dc99511941fa5ee41aa4f8c309cff052738e5993 (diff) | |
download | gcc-0b808489a2d152ccb85824e7bfd836a21342c021.tar.gz |
PR c++/64359
* pt.c (iterative_hash_template_arg): Hash alias specializations
differently from their TYPE_CANONICAL.
(alias_template_specialization_p): Optimize.
(template_args_equal): Optimize alias handling.
(dependent_alias_template_spec_p): Only check innermost args.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218995 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/pt.c | 49 |
2 files changed, 41 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7fcad878af7..8802e59b87d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-12-20 Jason Merrill <jason@redhat.com> + + PR c++/64359 + * pt.c (iterative_hash_template_arg): Hash alias specializations + differently from their TYPE_CANONICAL. + (alias_template_specialization_p): Optimize. + (template_args_equal): Optimize alias handling. + (dependent_alias_template_spec_p): Only check innermost args. + 2014-12-19 Kai Tietz <ktietz@redhat.com> PR c++/61198 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 15d304af635..f5bd842df0e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1674,6 +1674,18 @@ iterative_hash_template_arg (tree arg, hashval_t val) switch (tclass) { case tcc_type: + if (alias_template_specialization_p (arg)) + { + // We want an alias specialization that survived strip_typedefs + // to hash differently from its TYPE_CANONICAL, to avoid hash + // collisions that compare as different in template_args_equal. + // These could be dependent specializations that strip_typedefs + // left alone, or untouched specializations because + // coerce_template_parms returns the unconverted template + // arguments if it sees incomplete argument packs. + tree ti = TYPE_TEMPLATE_INFO (arg); + return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti)); + } if (TYPE_CANONICAL (arg)) return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), val); @@ -5314,13 +5326,19 @@ alias_type_or_template_p (tree t) bool alias_template_specialization_p (const_tree t) { - if (t == NULL_TREE) - return false; - - return (TYPE_P (t) - && TYPE_TEMPLATE_INFO (t) - && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t)) - && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t))); + /* It's an alias template specialization if it's an alias and its + TYPE_NAME is a specialization of a primary template. */ + if (TYPE_ALIAS_P (t)) + { + tree name = TYPE_NAME (t); + if (DECL_LANG_SPECIFIC (name)) + if (tree ti = DECL_TEMPLATE_INFO (name)) + { + tree tmpl = TI_TEMPLATE (ti); + return PRIMARY_TEMPLATE_P (tmpl); + } + } + return false; } /* Return TRUE iff T is a specialization of an alias template with @@ -5330,7 +5348,8 @@ bool dependent_alias_template_spec_p (const_tree t) { return (alias_template_specialization_p (t) - && any_dependent_template_arguments_p (TYPE_TI_ARGS (t))); + && (any_dependent_template_arguments_p + (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t))))); } /* Return the number of innermost template parameters in TMPL. */ @@ -7283,16 +7302,12 @@ template_args_equal (tree ot, tree nt) return false; /* Don't treat an alias template specialization with dependent arguments as equivalent to its underlying type when used as a - template argument; we need them to hash differently. */ - bool ndep = dependent_alias_template_spec_p (nt); - ++processing_template_decl; - bool odep = dependent_alias_template_spec_p (ot); - --processing_template_decl; - if (ndep != odep) + template argument; we need them to be distinct so that we + substitute into the specialization arguments at instantiation + time. And aliases can't be equivalent without being ==, so + we don't need to look any deeper. */ + if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot)) return false; - else if (ndep) - return (TYPE_TI_TEMPLATE (nt) == TYPE_TI_TEMPLATE (ot) - && template_args_equal (TYPE_TI_ARGS (nt), TYPE_TI_ARGS (ot))); else return same_type_p (ot, nt); } |