From: Mark Mitchell Date: Mon, 23 Nov 1998 14:41:37 +0000 (+0000) Subject: pt.c (instantiate_class_template): Don't try to figure out what specialization to... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6bdb985fc9a573ed779448cf5e31abffe062823e;p=gcc.git pt.c (instantiate_class_template): Don't try to figure out what specialization to use for a partial instantiation. * pt.c (instantiate_class_template): Don't try to figure out what specialization to use for a partial instantiation. Correct typos in a couple of comments. Avoid calling uses_template_parms multiple times. From-SVN: r23808 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7a7d3e1dfa6..ff7f5630c56 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +1998-11-23 Mark Mitchell + + * pt.c (instantiate_class_template): Don't try to figure out what + specialization to use for a partial instantiation. Correct + typos in a couple of comments. Avoid calling uses_template_parms + multiple times. + 1998-11-23 Benjamin Kosnik * method.c (process_overload_item): Add call to diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f41623977da..c8ecd4599b3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4452,6 +4452,7 @@ instantiate_class_template (type) { tree template, args, pattern, t; tree typedecl; + int is_partial_instantiation; if (type == error_mark_node) return error_mark_node; @@ -4465,29 +4466,52 @@ instantiate_class_template (type) argument coercion and such is simply lost. */ push_momentary (); + /* Figure out which template is being instantiated. */ template = most_general_template (CLASSTYPE_TI_TEMPLATE (type)); - args = CLASSTYPE_TI_ARGS (type); my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279); - t = most_specialized_class (template, args); - if (t == error_mark_node) + /* Figure out which arguments are being used to do the + instantiation. */ + args = CLASSTYPE_TI_ARGS (type); + is_partial_instantiation = uses_template_parms (args); + + if (is_partial_instantiation) + /* There's no telling which specialization is appropriate at this + point. Since all peeking at the innards of this partial + instantiation are extensions (like the "implicit typename" + extension, which allows users to omit the keyword `typename' on + names that are declared as types in template base classes), we + are free to do what we please. + + Trying to figure out which partial instantiation to use can + cause a crash. (Some of the template arguments don't even have + types.) So, we just use the most general version. */ + t = NULL_TREE; + else { - char *str = "candidates are:"; - cp_error ("ambiguous class template instantiation for `%#T'", type); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; t = TREE_CHAIN (t)) + t = most_specialized_class (template, args); + + if (t == error_mark_node) { - if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), - args)) + char *str = "candidates are:"; + cp_error ("ambiguous class template instantiation for `%#T'", type); + for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; + t = TREE_CHAIN (t)) { - cp_error_at ("%s %+#T", str, TREE_TYPE (t)); - str = " "; + if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), + args)) + { + cp_error_at ("%s %+#T", str, TREE_TYPE (t)); + str = " "; + } } + TYPE_BEING_DEFINED (type) = 1; + type = error_mark_node; + goto end; } - TYPE_BEING_DEFINED (type) = 1; - type = error_mark_node; - goto end; } - else if (t) + + if (t) pattern = TREE_TYPE (t); else pattern = TREE_TYPE (template); @@ -4523,14 +4547,14 @@ instantiate_class_template (type) args = inner_args; } - if (pedantic && uses_template_parms (args)) + if (pedantic && is_partial_instantiation) { - /* If there are still template parameters amongst the args, then - we can't instantiate the type; there's no telling whether or not one - of the template parameters might eventually be instantiated to some - value that results in a specialization being used. We do the - type as complete so that, for example, declaring one of its - members to be a friend will not be rejected. */ + /* If this is a partial instantiation, then we can't instantiate + the type; there's no telling whether or not one of the + template parameters might eventually be instantiated to some + value that results in a specialization being used. We do + mark the type as complete so that, for example, declaring one + of its members to be a friend will not be rejected. */ TYPE_SIZE (type) = integer_zero_node; goto end; } @@ -4603,7 +4627,7 @@ instantiate_class_template (type) /* If this is a partial instantiation, don't tsubst anything. We will only use this type for implicit typename, so the actual contents don't matter. All that matters is whether a particular name is a type. */ - if (uses_template_parms (type)) + if (is_partial_instantiation) { TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern); TYPE_FIELDS (type) = TYPE_FIELDS (pattern); @@ -7335,7 +7359,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) return 0; /* If PARM uses template parameters, then we can't bail out here, - even in ARG == PARM, since we won't record unifications for the + even if ARG == PARM, since we won't record unifications for the template parameters. We might need them if we're trying to figure out which of two things is more specialized. */ if (arg == parm && !uses_template_parms (parm)) diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec25.C b/gcc/testsuite/g++.old-deja/g++.pt/spec25.C new file mode 100644 index 00000000000..884abf07dee --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec25.C @@ -0,0 +1,15 @@ +// Build don't link: + +template +struct S { +}; + +template +struct S { +}; + +template +void f () +{ + S s; +}