This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH for minor pt.c cleanup



This patch just simplifies code a little in the wake of recent
changes.  As a bonus, there's a fix for a crash involving invalid
typename types.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1999-03-02  Mark Mitchell  <mark@markmitchell.com>

	* cp-tree.h (determine_specialization): Don't declare.
	* pt.c (determine_specialization): Make it static.  Eliminate
	complain parameter.  Note that decl is always non-NULL now, and
	simplify accordingly.
	(tsubst): Catch illegal typename substitutions.

Index: crash30.C
===================================================================
RCS file: crash30.C
diff -N crash30.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- crash30.C	Tue Mar  2 23:43:25 1999
***************
*** 0 ****
--- 1,15 ----
+ // Build don't link:
+ 
+ extern "C" int printf(const char *, ...);
+ template <class T> struct A {
+   typedef typename T::X B; // ERROR - not a class
+   A(double);
+ };
+  
+ template <class T> void xxx(typename A<T>::B);
+  
+ template <class T> struct B {
+   friend void xxx<T>(T); // ERROR - does not match any template
+ };
+  
+ template struct B<double>; // ERROR - 
Index: testsuite/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.199
diff -c -p -r1.199 cp-tree.h
*** cp-tree.h	1999/02/21 16:38:10	1.199
--- cp-tree.h	1999/03/02 21:40:25
*************** extern void reset_specialization        
*** 3053,3059 ****
  extern void end_specialization                  PROTO((void));
  extern void begin_explicit_instantiation        PROTO((void));
  extern void end_explicit_instantiation          PROTO((void));
- extern tree determine_specialization            PROTO((tree, tree, tree *, int, int));
  extern tree check_explicit_specialization       PROTO((tree, tree, int, int));
  extern tree process_template_parm		PROTO((tree, tree));
  extern tree end_template_parm_list		PROTO((tree));
--- 3053,3058 ----
Index: testsuite/cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.264
diff -c -p -r1.264 pt.c
*** pt.c	1999/02/21 16:38:19	1.264
--- pt.c	1999/03/02 21:40:44
*************** static tree get_template_base PROTO((tre
*** 148,153 ****
--- 148,154 ----
  static tree try_class_unification PROTO((tree, tree, tree, tree));
  static int coerce_template_template_parms PROTO((tree, tree, int,
  						 tree, tree));
+ static tree determine_specialization PROTO((tree, tree, tree *, int));
  
  /* We use TREE_VECs to hold template arguments.  If there is only one
     level of template arguments, then the TREE_VEC contains the
*************** print_candidates (fns)
*** 917,934 ****
     are output in a newly created vector *TARGS_OUT.
  
     If it is impossible to determine the result, an error message is
!    issued, unless COMPLAIN is 0.  In any case, error_mark_node is
!    returned to indicate failure.  */
  
  tree
  determine_specialization (template_id, decl, targs_out, 
! 			  need_member_template,
! 			  complain)
       tree template_id;
       tree decl;
       tree* targs_out;
       int need_member_template;
-      int complain;
  {
    tree fn;
    tree fns;
--- 918,932 ----
     are output in a newly created vector *TARGS_OUT.
  
     If it is impossible to determine the result, an error message is
!    issued.  The error_mark_node is returned to indicate failure.  */
  
  tree
  determine_specialization (template_id, decl, targs_out, 
! 			  need_member_template)
       tree template_id;
       tree decl;
       tree* targs_out;
       int need_member_template;
  {
    tree fn;
    tree fns;
*************** determine_specialization (template_id, d
*** 973,982 ****
  	/* This is just an ordinary non-member function.  Nothing can
  	   be a specialization of that.  */
  	continue;
-       else if (!decl)
- 	/* When there's no DECL to match, we know we're looking for
- 	   non-members.  */
- 	continue;
        else
  	{
  	  tree decl_arg_types;
--- 971,976 ----
*************** determine_specialization (template_id, d
*** 1010,1034 ****
  	  continue;
  	}
  
!       if (decl == NULL_TREE)
! 	{
! 	  /* Unify against ourselves to make sure that the args we have
! 	     make sense and there aren't any undeducible parms.  It's OK if
! 	     not all the parms are specified; they might be deduced
! 	     later. */
! 	  targs = get_bindings_overload (tmpl, DECL_RESULT (tmpl),
! 					 explicit_targs);
! 	  if (uses_template_parms (targs))
! 	    /* We couldn't deduce all the arguments.  */
! 	    continue;
! 	}
!       else
! 	/* See whether this function might be a specialization of this
! 	   template.  */
! 	targs = get_bindings (tmpl, decl, explicit_targs);
  
        if (!targs)
! 	/* Wwe cannot deduce template arguments that when used to
  	   specialize TMPL will produce DECL.  */
  	continue;
  
--- 1004,1015 ----
  	  continue;
  	}
  
!       /* See whether this function might be a specialization of this
! 	 template.  */
!       targs = get_bindings (tmpl, decl, explicit_targs);
  
        if (!targs)
! 	/* We cannot deduce template arguments that when used to
  	   specialize TMPL will produce DECL.  */
  	continue;
  
*************** determine_specialization (template_id, d
*** 1036,1042 ****
        templates = scratch_tree_cons (targs, tmpl, templates);
      }
  
!   if (decl && templates && TREE_CHAIN (templates))
      {
        /* We have:
  	 
--- 1017,1023 ----
        templates = scratch_tree_cons (targs, tmpl, templates);
      }
  
!   if (templates && TREE_CHAIN (templates))
      {
        /* We have:
  	 
*************** determine_specialization (template_id, d
*** 1079,1099 ****
  
    if (templates == NULL_TREE && candidates == NULL_TREE)
      {
!       if (complain)
! 	cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
! 		     template_id, decl);
        return error_mark_node;
      }
    else if ((templates && TREE_CHAIN (templates))
! 	   || (candidates && TREE_CHAIN (candidates)))
      {
!       if (complain)
! 	{
! 	  cp_error_at ("ambiguous template specialization `%D' for `%+D'",
! 		       template_id, decl);
! 	  chainon (candidates, templates);
! 	  print_candidates (candidates);
! 	}
        return error_mark_node;
      }
  
--- 1060,1077 ----
  
    if (templates == NULL_TREE && candidates == NULL_TREE)
      {
!       cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
! 		   template_id, decl);
        return error_mark_node;
      }
    else if ((templates && TREE_CHAIN (templates))
! 	   || (candidates && TREE_CHAIN (candidates))
! 	   || (templates && candidates))
      {
!       cp_error_at ("ambiguous template specialization `%D' for `%+D'",
! 		   template_id, decl);
!       chainon (candidates, templates);
!       print_candidates (candidates);
        return error_mark_node;
      }
  
*************** check_explicit_specialization (declarato
*** 1445,1452 ****
  	 declaration.  */
        tmpl = determine_specialization (declarator, decl,
  				       &targs, 
! 				       member_specialization,
! 				       1);
  	    
        if (!tmpl || tmpl == error_mark_node)
  	/* We couldn't figure out what this declaration was
--- 1423,1429 ----
  	 declaration.  */
        tmpl = determine_specialization (declarator, decl,
  				       &targs, 
! 				       member_specialization);
  	    
        if (!tmpl || tmpl == error_mark_node)
  	/* We couldn't figure out what this declaration was
*************** tsubst_friend_function (decl, args)
*** 4366,4373 ****
        new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
        tmpl = determine_specialization (template_id, new_friend,
  				       &new_args, 
! 				       /*need_member_template=*/0, 
! 				       /*complain=*/1);
        new_friend = instantiate_template (tmpl, new_args);
        goto done;
      }
--- 4343,4349 ----
        new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
        tmpl = determine_specialization (template_id, new_friend,
  				       &new_args, 
! 				       /*need_member_template=*/0);
        new_friend = instantiate_template (tmpl, new_args);
        goto done;
      }
*************** tsubst (t, args, complain, in_decl)
*** 6039,6046 ****
  	       Type deduction may fail for any of the following
  	       reasons:  
  
! 	         Attempting to create an array with a size that is
! 	         zero or negative.  */
  	    if (complain)
  	      cp_error ("creating array with size `%E'", max);
  
--- 6015,6022 ----
  	       Type deduction may fail for any of the following
  	       reasons:  
  
! 		 Attempting to create an array with a size that is
! 		 zero or negative.  */
  	    if (complain)
  	      cp_error ("creating array with size `%E'", max);
  
*************** tsubst (t, args, complain, in_decl)
*** 6403,6418 ****
  	if (ctx == error_mark_node || f == error_mark_node)
  	  return error_mark_node;
  
! 	/* Normally, make_typename_type does not require that the CTX
! 	   have complete type in order to allow things like:
  	     
!              template <class T> struct S { typename S<T>::X Y; };
  
! 	   But, such constructs have already been resolved by this
! 	   point, so here CTX really should have complete type, unless
! 	   it's a partial instantiation.  */
! 	if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
! 	  {
  	    ctx = complete_type (ctx);
  	    if (!TYPE_SIZE (ctx))
  	      {
--- 6379,6401 ----
  	if (ctx == error_mark_node || f == error_mark_node)
  	  return error_mark_node;
  
! 	if (!IS_AGGR_TYPE (ctx))
! 	  {
! 	    if (complain)
! 	      cp_error ("`%T' is not a class, struct, or union type",
! 			ctx);
! 	    return error_mark_node;
! 	  }
! 	else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
! 	  {
! 	    /* Normally, make_typename_type does not require that the CTX
! 	       have complete type in order to allow things like:
  	     
! 	         template <class T> struct S { typename S<T>::X Y; };
  
! 	       But, such constructs have already been resolved by this
! 	       point, so here CTX really should have complete type, unless
! 	       it's a partial instantiation.  */
  	    ctx = complete_type (ctx);
  	    if (!TYPE_SIZE (ctx))
  	      {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]