diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-08-18 14:48:58 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-08-18 14:52:22 -0700 |
commit | ea2722934fc8238e4a9eb41586ca106448faa940 (patch) | |
tree | ce2fde11745762f99642d927dde02cf4bb91e4cd | |
parent | 94bedeaf694c728607a718d599edb4d74a2813c0 (diff) | |
download | gcc-ea2722934fc8238e4a9eb41586ca106448faa940.zip gcc-ea2722934fc8238e4a9eb41586ca106448faa940.tar.gz gcc-ea2722934fc8238e4a9eb41586ca106448faa940.tar.bz2 |
c++: alias template template_info setting
During the construction of alias templates we can alter its
template_info. This is really weird, because that's morally immutable
data. In this case it's ok, but let's not create a duplicate
template_info, and add asserts to make sure it is changing in exactly
the way we expect.
gcc/cp/
* cp-tree.h (SET_TYPE_TEMPLTE_INFO): Do not deal with ALIAS templates.
* pt.c (lookup_template_class_1): Special-case alias template
template_info setting.
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/pt.c | 22 |
2 files changed, 25 insertions, 8 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5ba82ee6..44531cd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3485,13 +3485,12 @@ struct GTY(()) lang_decl { ? TYPE_ALIAS_TEMPLATE_INFO (NODE) \ : TYPE_TEMPLATE_INFO (NODE)) -/* Set the template information for an ENUMERAL_, RECORD_, or - UNION_TYPE to VAL. */ +/* Set the template information for a non-alias n ENUMERAL_, RECORD_, + or UNION_TYPE to VAL. ALIAS's are dealt with separately. */ #define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \ - (TREE_CODE (NODE) == ENUMERAL_TYPE \ - || (CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE)) \ - ? (TYPE_LANG_SLOT_1 (NODE) = (VAL)) \ - : (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL))) + (gcc_checking_assert (TREE_CODE (NODE) == ENUMERAL_TYPE \ + || (CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE))), \ + (TYPE_LANG_SLOT_1 (NODE) = (VAL))) \ #define TI_TEMPLATE(NODE) \ ((struct tree_template_info*)TEMPLATE_INFO_CHECK (NODE))->tmpl diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8ad91b3..edaefcf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10088,8 +10088,26 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, } } - // Build template info for the new specialization. - SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); + /* Build template info for the new specialization. */ + if (TYPE_ALIAS_P (t)) + { + /* This is constructed during instantiation of the alias + decl. But for member templates of template classes, that + is not correct as we need to refer to the partially + instantiated template, not the most general template. + The incorrect knowledge will not have escaped this + instantiation process, so we're good just updating the + template_info we made then. */ + tree ti = DECL_TEMPLATE_INFO (TYPE_NAME (t)); + gcc_checking_assert (template_args_equal (TI_ARGS (ti), arglist)); + if (TI_TEMPLATE (ti) != found) + { + gcc_checking_assert (DECL_TI_TEMPLATE (found) == TI_TEMPLATE (ti)); + TI_TEMPLATE (ti) = found; + } + } + else + SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); elt.spec = t; slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT); |