Updated patch for g++-980308: bug in template template parameter implementation again

Kriang Lerdsuwanakij lerdsuwa@scf-fs.usc.edu
Fri Mar 20 10:51:00 GMT 1998


Hi

Here is my updated version of the patch at

  http://www.cygnus.com/ml/egcs-bugs/1998-Mar/0317.html

Some unnecessary function calls and memory allocation in tsubst changes 
are removed in this version.

--Kriang

	* pt.c (complete_template_args): New function.
	(get_bindings): Deal with specializations of function templates
	with return type containing parameters from outer class 
	templates.

	(tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level,
	alos substitute arguments.


*** pt.c	1998/03/17 05:39:06	1.7
--- pt.c	1998/03/20 17:53:28
*************** static tree get_class_bindings PROTO((tr
*** 81,86 ****
--- 81,87 ----
  static tree coerce_template_parms PROTO((tree, tree, tree, int, int, int));
  static tree tsubst_enum	PROTO((tree, tree, tree *));
  static tree add_to_template_args PROTO((tree, tree));
+ static tree complete_template_args PROTO((tree, tree));
  static int  type_unification_real PROTO((tree, tree *, tree, tree,
  					 int, int, int));
  static void note_template_header PROTO((int));
*************** is_member_template (t)
*** 339,344 ****
--- 340,413 ----
    return 0;
  }
  
+ /* Return a new template argument vector which contains all of ARGS
+    for all outer templates TYPE is contained in, but has as its 
+    innermost set of arguments the EXTRA_ARGS.  */
+ 
+ static tree
+ complete_template_args (decl, extra_args)
+      tree decl;
+      tree extra_args;
+ {
+   int depth;
+   tree type;
+   
+   my_friendly_assert (TREE_CODE (decl) == TEMPLATE_DECL, 0);
+   my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0);
+ 
+   decl = DECL_TEMPLATE_RESULT (decl);
+   type = DECL_REAL_CONTEXT (decl);
+ 
+   /* For constructor and destructor, it can be template simply
+      because the class it belongs to is.  If this is the case,
+      it and its context share the same template arguments and
+      we don't want its context in template_class_depth 
+      computation.  */
+ 
+   if (DECL_LANG_SPECIFIC (decl) && DECL_CONSTRUCTOR_P (decl))
+     {
+       /* Check whether its context is a template class.  */
+       if (CLASSTYPE_TEMPLATE_INFO (type)
+ 	  && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
+ 	  && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ 	{
+ 	  if (comp_template_args (CLASSTYPE_TI_ARGS (type),
+ 				  DECL_TI_ARGS (decl)))
+ 	    type = TYPE_CONTEXT (type);
+ 
+ 	}
+     }
+   else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+     {
+       /* There is no template destructors.  */
+       type = TYPE_CONTEXT (type);
+     }
+   
+   depth = template_class_depth (type);
+   if (depth)
+     {
+       tree new_args = make_tree_vec (depth + 1);
+ 
+       for (; type && TREE_CODE (type) != FUNCTION_DECL;
+ 	   type = TYPE_CONTEXT (type))
+ 	{
+ 	  if (CLASSTYPE_TEMPLATE_INFO (type)
+ 	      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
+ 	      && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ 	    {
+ 	      --depth;
+ 	      TREE_VEC_ELT (new_args, depth) = CLASSTYPE_TI_ARGS (type);
+ 	    }
+ 	}
+ 
+       TREE_VEC_ELT (new_args, 
+ 		    TREE_VEC_LENGTH (new_args) - 1) = extra_args;
+       extra_args = new_args;
+     }
+ 
+   return extra_args;
+ }
+ 
  /* Return a new template argument vector which contains all of ARGS,
     but has as its innermost set of arguments the EXTRA_ARGS.  */
  
*************** tsubst (t, args, in_decl)
*** 3575,3580 ****
--- 3644,3657 ----
  	    TYPE_MAIN_VARIANT (r) = r;
  	    TYPE_POINTER_TO (r) = NULL_TREE;
  	    TYPE_REFERENCE_TO (r) = NULL_TREE;
+ 
+ 	    if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+ 		&& CLASSTYPE_TEMPLATE_INFO (t))
+ 	      {
+ 		tree argvec = tsubst (CLASSTYPE_TI_ARGS (t), args, in_decl);
+ 		CLASSTYPE_TEMPLATE_INFO (r)
+ 		  = perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
+ 	      }
  	    break;
  
  	  case TEMPLATE_PARM_INDEX:
*************** get_bindings (fn, decl, explicit_args)
*** 5745,5751 ****
    if (i == 0)
      {
        /* Check to see that the resulting return type is also OK.  */
!       tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, NULL_TREE);
  
        if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
  	return NULL_TREE;
--- 5822,5830 ----
    if (i == 0)
      {
        /* Check to see that the resulting return type is also OK.  */
!       tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), 
! 		       complete_template_args (fn, targs),
! 		       NULL_TREE);
  
        if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
  	return NULL_TREE;




More information about the Gcc-bugs mailing list