From: Nathan Sidwell Date: Tue, 18 Aug 2020 21:48:58 +0000 (-0700) Subject: c++: alias template template_info setting X-Git-Tag: basepoints/gcc-12~5506 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea2722934fc8238e4a9eb41586ca106448faa940;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5ba82ee60db3..44531cd86dc7 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 8ad91b37297a..edaefcf505f1 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);