Message ID | m3hbha154q.fsf@seketeli.org |
---|---|
State | New |
Headers | show |
On 09/28/2010 07:25 AM, Dodji Seketeli wrote: > I must be missing something. In structural_comptype, in the RECORD_TYPE > case, comp_template_args is called and I think this eventually compares > the template parms of A and A' using their canonical types, even though > we are calling from structural_comptype and are supposed to do > structural comparison. Right. > Hence A and A' will is considered structurally > equivalent. No? I don't see why; the template parms of A and A' should have different canonical types. > Just to be sure I understand; do you mean I should write a function that > recursively does type substitution for non-type parms (only) of template > template parms and use that in the fixup? Or does such a function exists > already? The former. Or rather, that fixup_template_parms_canonical_types should work this way. Incidentally, I notice that it still does two passes over the parm list. > This hunk -- similar to what is done in lookup_template_class in the > "if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))" branch -- seems to fix the > issue: Looks good. Jason
Jason Merrill <jason@redhat.com> writes: > On 09/28/2010 07:25 AM, Dodji Seketeli wrote: >> I must be missing something. In structural_comptype, in the RECORD_TYPE >> case, comp_template_args is called and I think this eventually compares >> the template parms of A and A' using their canonical types, even though >> we are calling from structural_comptype and are supposed to do >> structural comparison. > > Right. > >> Hence A and A' will is considered structurally >> equivalent. No? > > I don't see why; the template parms of A and A' should have different > canonical types. Ah, I wasn't clear. During the fixup, at some point, A and A' have the same template parm actually. Because A's template parm (let's call it T) saw its canonical type updated, and then, T got substituted into A to create A'. But then A kept its canonical type, even thoug T's canonical type changed. And A' has another canonical type, different from the one of A. > >> Just to be sure I understand; do you mean I should write a function that >> recursively does type substitution for non-type parms (only) of template >> template parms and use that in the fixup? Or does such a function exists >> already? > > The former. Or rather, that fixup_template_parms_canonical_types > should work this way. Okay, thanks, working on that now. > Incidentally, I notice that it still does two > passes over the parm list. Oops, okay I will address that.
On 09/29/2010 03:05 PM, Dodji Seketeli wrote: > Ah, I wasn't clear. During the fixup, at some point, A and A' have the > same template parm actually. Because A's template parm (let's call it T) > saw its canonical type updated Well, that's the problem then. You shouldn't be modifying the template parms that you started out with, you should be replacing them with new ones. Jason
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e060cc7..bf13978 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14914,6 +14914,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) { tree parmvec = TYPE_TI_ARGS (parm); tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg)); + tree full_argvec = add_to_template_args (targs, argvec); tree parm_parms = DECL_INNERMOST_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm)); @@ -14948,7 +14949,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) the global operator+ will be used; if they are not, the Lvalue_proxy will be converted to float. */ if (coerce_template_parms (parm_parms, - argvec, + full_argvec, TYPE_TI_TEMPLATE (parm), tf_none, /*require_all_args=*/true,