On 2013-11-09 13:21, Adam Butcher wrote:
On 2013-11-08 18:50, Jason Merrill wrote:
On 10/31/2013 05:47 AM, Adam Butcher wrote:
+         become_template = true;

+         push_deferring_access_checks (dk_deferred);

Why is this call here?  I don't see anything in the rest of the
function that would trigger an access check, or a matching pop.

This is only in the 'fully implicit function template' case; and the
matching pop is in finish_fully_implicit_template.  It was in the
original impl which was trying to do all the things that beginning and
ending an explicit template parameter list did.  Maybe this is
unnecessary.  I'll see if anything breaks if I remove it.

+ /* Create a distinct parameter pack type from the current parm and add it + to the replacement args to tsubst below into the generic function
+        parameter.  */
+
+ tree t = copy_type (TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i))));
+      TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);

Is this changing anything?  I'm not sure if we need to copy the decl
or if we can just reuse it, but either way we need to set the type of
TEMPLATE_TYPE_DECL (t) to t.

I think it (or at least one of the assignments) is necessary.  It is
derived from some similar code in tsubst. I'll have another look into
it and add TREE_TYPE (TEMPLATE_TYPE_DECL (t)) = t also.  What problem
will be caused by not setting the latter; is it a consistency issue?
I have not seen any probs in testing so far.

+      SET_TYPE_STRUCTURAL_EQUALITY (t);

Why not

      TYPE_CANONICAL (t) = canonical_type_parameter (t);

?

Only for the sake of not exposing this (currently static) function
from pt.c (or moving the pack convert function into pt.c).  My
original impl did extern canonical_type_parameter and use that and I
think it worked as expected.  Would that be preferred?

The following update appears to work.

Cheers,
Adam

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index be799a0..aba4a09 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -31270,8 +31270,6 @@ synthesize_implicit_template_parm  (cp_parser *parser)
 
 	  become_template = true;
 
-	  push_deferring_access_checks (dk_deferred);
-
 	  parser->implicit_template_scope
 	      = begin_scope (sk_template_parms, NULL);
 
@@ -31362,10 +31360,12 @@ convert_generic_types_to_packs (tree parm,
 	 parameter.  */
 
       tree t = copy_type (TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i))));
+      TREE_TYPE (TEMPLATE_TYPE_DECL (t)) = t;
       TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);
       TYPE_MAIN_VARIANT (t) = t;
       TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
-      SET_TYPE_STRUCTURAL_EQUALITY (t);
+      extern tree canonical_type_parameter (tree);
+      TYPE_CANONICAL (t) = canonical_type_parameter (t);
       TREE_VEC_ELT (replacement, i) = t;
     }
 
@@ -31406,7 +31406,6 @@ finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
       DECL_VIRTUAL_P (member_decl_opt) = false;
     }
 
-  pop_deferring_access_checks ();
   if (member_decl_opt)
     member_decl_opt = finish_member_template_decl (member_decl_opt);
   end_template_decl ();
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8c1553f..d3047cb 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3546,7 +3546,7 @@ build_template_parm_index (int index,
    parameter.  Returns the canonical type parameter, which may be TYPE
    if no such parameter existed.  */
 
-static tree
+tree
 canonical_type_parameter (tree type)
 {
   tree list;

Reply via email to