aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-08-18 14:48:58 -0700
committerNathan Sidwell <nathan@acm.org>2020-08-18 14:52:22 -0700
commitea2722934fc8238e4a9eb41586ca106448faa940 (patch)
treece2fde11745762f99642d927dde02cf4bb91e4cd
parent94bedeaf694c728607a718d599edb4d74a2813c0 (diff)
downloadgcc-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.h11
-rw-r--r--gcc/cp/pt.c22
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);