Patch for template unification with arrays

Mark Mitchell mmitchell@usa.net
Wed Feb 11 16:02:00 GMT 1998


Jason --
 
Here's a patch for code like this:

  struct foo {
      template <typename T, int N>
      static T* array_end(T(&array)[N]) { return &array[N]; }
  };

  main(int ac, char* av[]) {
      int i[] = {1,2,3,4,5,6,7};
      int* e = foo::array_end(i);
  }

which didn't use to work correctly.  Is it OK to check this in?  Also,
why does call.c contain the following, in build_new_function_call:

      if (! any_viable (candidates))
	{
	  if (candidates && ! candidates->next)
	    return build_function_call (candidates->fn, args);

This code allows (silently) a function call to succeed if there is
only one candidate.  Furthermore, we don't do this in other places
in call.c so member functions are not treated in this lenient
fashion. 

-- 
Mark Mitchell		mmitchell@usa.net
Stanford University	http://www.stanford.edu

Wed Feb 11 16:01:20 1998  Mark Mitchell  <mmitchell@usa.net>

	* decl.c (complete_array_type): Build index types on the permanent
	obstack. 
	(grokdeclarator): Likewise.
	* pt.c (tsubst): Always create index types with build_index_type
	so that we get canonical index types.
	
Index: gcc/cp/decl.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl.c,v
retrieving revision 1.25
diff -c -p -r1.25 decl.c
*** decl.c	1998/02/11 19:03:02	1.25
--- decl.c	1998/02/11 22:47:02
*************** complete_array_type (type, initial_value
*** 7297,7303 ****
      {
        tree itype;
  
!       TYPE_DOMAIN (type) = build_index_type (maxindex);
        if (! TREE_TYPE (maxindex))
  	TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
        if (initial_value)
--- 7297,7311 ----
      {
        tree itype;
  
!       /* We make sure to build the index type on the permanent_obstack
! 	 so that we will get a canonical index type.  These types must
! 	 be canonical since some comparisons to see if two array types are
! 	 the same depend on checking the TYPE_MAIN_VARIANT of the
! 	 array, and those fields will only be the same if the
! 	 index_types are canonical.  */
!       push_obstacks (&permanent_obstack, &permanent_obstack);
!       TYPE_DOMAIN (type) = build_index_type (copy_to_permanent (maxindex));
!       pop_obstacks ();
        if (! TREE_TYPE (maxindex))
  	TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
        if (initial_value)
*************** grokdeclarator (declarator, declspecs, d
*** 8852,8867 ****
  		/* If we're a parm, we need to have a permanent type so
                     mangling checks for re-use will work right.  If both the
                     element and index types are permanent, the array type
!                    will be, too.  */
! 		if (decl_context == PARM
! 		    && allocation_temporary_p () && TREE_PERMANENT (type))
! 		  {
! 		    push_obstacks (&permanent_obstack, &permanent_obstack);
! 		    itype = build_index_type (itype);
! 		    pop_obstacks ();
! 		  }
! 		else
! 		  itype = build_index_type (itype);
  
  	      dont_grok_size:
  		resume_momentary (yes);
--- 8860,8871 ----
  		/* If we're a parm, we need to have a permanent type so
                     mangling checks for re-use will work right.  If both the
                     element and index types are permanent, the array type
!                    will be, too.  In fact, the index type must always
! 		   be canonical; see the comment in
! 		   complete_array_type.  */
! 		push_obstacks (&permanent_obstack, &permanent_obstack);
! 		itype = build_index_type (itype);
! 		pop_obstacks ();
  
  	      dont_grok_size:
  		resume_momentary (yes);
Index: gcc/cp/pt.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/pt.c,v
retrieving revision 1.26
diff -c -p -r1.26 pt.c
*** pt.c	1998/02/11 19:03:37	1.26
--- pt.c	1998/02/11 21:49:04
*************** tsubst (t, args, nargs, in_decl)
*** 3889,3894 ****
--- 3889,3897 ----
  	tree r;
  	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
  	  return t;
+ 	/* The tsbust'd domain type is not the canonical one, most
+ 	   likely, so we must recreate it.  */
+ 	domain = build_index_type (TYPE_MAX_VALUE (domain));
  	r = build_cplus_array_type (type, domain);
  	return r;
        }
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.pt
Index: gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C
===================================================================
RCS file: memtemp69.C
diff -N memtemp69.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- memtemp69.C	Wed Feb 11 14:25:00 1998
***************
*** 0 ****
--- 1,27 ----
+ struct S 
+ {
+   template <class T>
+   void f(T (&i)[7])
+     {}
+ 
+   void g()
+     {
+       int i[] = {1, 2, 3, 4, 5, 6, 7};
+       f(i);
+       int j[7];
+       f(j);
+     }
+ };
+ 
+ struct foo {
+   template <typename T, int N>
+   static T* array_end(T(&array)[N]) { return &array[N]; }
+ };
+ 
+ main(int ac, char* av[]) {
+   S s;
+   s.g();
+   int i[] = {1,2,3,4,5};
+   int* e = foo::array_end(i);
+ }
+  



More information about the Gcc-bugs mailing list