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.
Needless to say modules fell over the duplicated template_info and got
very confused.
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.
--
Nathan Sidwell
diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h
index 04758574019..5f2c7e574c4 100644
--- i/gcc/cp/cp-tree.h
+++ w/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 i/gcc/cp/pt.c w/gcc/cp/pt.c
index b80fe0a5cc5..ada0438f272 100644
--- i/gcc/cp/pt.c
+++ w/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);