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 to avoid template crash



Here's a patch to fix a case where we attempted to instantiate a
declaration more than once, and confused ourselves in the process.

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

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

	* decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
	merging decls.
	* pt.c (regenerate_decl_from_template): Tweak for clarity.
	(instantiate_decl): Mark a decl instantiated before regenerating
	it to avoid recursion.
	* tree.c (mapcar): Don't call decl_constant_value unless we know
	something is TREE_READONLY_DECL_P.

	* class.c (check_for_override): Don't stop checking when we find
	the first overridden function.  Delete #if 0'd code.
	* search.c (get_matching_virtual): Likewise.
	
Index: testsuite/g++.old-deja/g++.pt/crash29.C
===================================================================
RCS file: crash29.C
diff -N crash29.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- crash29.C	Fri Feb 26 11:46:41 1999
***************
*** 0 ****
--- 1,69 ----
+ // Build don't link:
+ // Origin: Steven Parkes <parkes@sierravista.com>
+ 
+ typedef unsigned int size_t;
+ 
+ class UUId {};
+ 
+ template <class T> class MetaClass;
+ 
+ class TypeInfo;
+ 
+ struct MetaClassGeneric 
+ {
+                                 MetaClassGeneric( TypeInfo& );
+ };
+ 
+ struct TypeInfo 
+ {
+                         void    (*constructor)( void* );
+                         void    initialize( void* );
+ };
+ 
+ template <class T>
+ class TypeIDInit {
+ public:
+                                 TypeIDInit();
+                  static void    initialize();
+              static TypeInfo    info;
+                   static int    storage[];
+                  static void    metaclassConstructor( void* );
+ };
+ 
+ template <class T>
+ TypeInfo TypeIDInit<T>::info = 
+ {
+   TypeIDInit<T>::metaclassConstructor
+ };
+ 
+ template <class T>
+ inline
+ TypeIDInit<T>::TypeIDInit()
+ {
+   info.initialize(storage);
+ }
+ 
+ template <class T>
+ class NameInfo : public MetaClassGeneric {
+ public:
+                                 NameInfo() 
+ 				: MetaClassGeneric( TypeIDInit<T>::info ) {}
+ };
+ 
+ class MetaClass<UUId>
+ : public NameInfo<UUId>
+ {
+ };
+ 
+ extern "C++"
+ inline void *operator new(size_t, void *place) throw() { return place; }
+ 
+ template <class T>
+ void
+ TypeIDInit<T>::metaclassConstructor( void* place )
+ {
+   new ( place ) MetaClass<T>;
+ }
+ 
+ template class   TypeIDInit<UUId>   ;
+ 
Index: testsuite/cp/decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.312
diff -c -p -r1.312 decl.c
*** decl.c	1999/02/21 16:38:14	1.312
--- decl.c	1999/02/26 19:46:54
*************** duplicate_decls (newdecl, olddecl)
*** 3319,3324 ****
--- 3319,3326 ----
        DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
        DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
        DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
+       DECL_TEMPLATE_INSTANTIATED (newdecl) 
+ 	|= DECL_TEMPLATE_INSTANTIATED (olddecl);
        /* Don't really know how much of the language-specific
  	 values we should copy from old to new.  */
        DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
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/02/26 19:47:05
*************** regenerate_decl_from_template (decl, tmp
*** 9047,9054 ****
        /* Pop the class context we pushed above.  */
        popclass (1);
      }
! 
!   if (TREE_CODE (decl) == FUNCTION_DECL)
      {
        /* Convince duplicate_decls to use the DECL_ARGUMENTS from the
  	 new decl.  */ 
--- 9047,9053 ----
        /* Pop the class context we pushed above.  */
        popclass (1);
      }
!   else if (TREE_CODE (decl) == FUNCTION_DECL)
      {
        /* Convince duplicate_decls to use the DECL_ARGUMENTS from the
  	 new decl.  */ 
*************** instantiate_decl (d)
*** 9243,9250 ****
        goto out;
      }
  
!   regenerate_decl_from_template (d, td);
    DECL_TEMPLATE_INSTANTIATED (d) = 1;
  
    /* We already set the file and line above.  Reset them now in case
       they changed as a result of calling regenerate_decl_from_template.  */
--- 9242,9255 ----
        goto out;
      }
  
!   /* We're now committed to instantiating this template.  Mark it as
!      instantiated so that recursive calls to instantiate_decl do not
!      try to instantiate it again.  */
    DECL_TEMPLATE_INSTANTIATED (d) = 1;
+ 
+   /* Regenerate the declaration in case the template has been modified
+      by a subsequent redeclaration.  */
+   regenerate_decl_from_template (d, td);
  
    /* We already set the file and line above.  Reset them now in case
       they changed as a result of calling regenerate_decl_from_template.  */
Index: testsuite/cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.96
diff -c -p -r1.96 tree.c
*** tree.c	1999/02/18 20:44:21	1.96
--- tree.c	1999/02/26 19:47:08
*************** mapcar (t, func)
*** 1846,1856 ****
             void g() { const int i = 7; f<i>(7); }
  
  	 however, we must actually return the constant initializer.  */
!       tmp = decl_constant_value (t);
!       if (tmp != t)
! 	return mapcar (tmp, func);
!       else
! 	return error_mark_node;
  
      case PARM_DECL:
        {
--- 1846,1858 ----
             void g() { const int i = 7; f<i>(7); }
  
  	 however, we must actually return the constant initializer.  */
!       if (TREE_READONLY_DECL_P (t))
! 	{
! 	  tmp = decl_constant_value (t);
! 	  if (tmp != t)
! 	    return mapcar (tmp, func);
! 	}
!       return error_mark_node;
  
      case PARM_DECL:
        {


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