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: Fix mangling of destructors with virtual bases



We were mis-mangling the destructors for classes with virtual bases.
In particular, we were encoding the type of the VTT parameter as part
of the function type, which is unncessary.

Tested on i686-pc-linux-gnu, committed on the mainline and the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-02-22  Mark Mitchell  <mark@codesourcery.com>

	* mangle.c (write_encoding): Pass write_function_type the
	FUNCTION_DECL for the function being encoded.
	(write_function_type): Pass it along to write_bare_function_type.
	(write_bare_function_type): Pass it along to write_method_parms.
	(write_method_parms): Don't mangle the compiler-generated
	parameters to a constructor or destructor.

Index: mangle.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/mangle.c,v
retrieving revision 1.26
diff -c -p -r1.26 mangle.c
*** mangle.c	2001/01/25 07:35:20	1.26
--- mangle.c	2001/02/22 21:29:22
*************** static void write_type PARAMS ((tree));
*** 163,170 ****
  static int write_CV_qualifiers_for_type PARAMS ((tree));
  static void write_builtin_type PARAMS ((tree));
  static void write_function_type PARAMS ((tree));
! static void write_bare_function_type PARAMS ((tree, int));
! static void write_method_parms PARAMS ((tree, int));
  static void write_class_enum_type PARAMS ((tree));
  static void write_template_args PARAMS ((tree));
  static void write_expression PARAMS ((tree));
--- 163,170 ----
  static int write_CV_qualifiers_for_type PARAMS ((tree));
  static void write_builtin_type PARAMS ((tree));
  static void write_function_type PARAMS ((tree));
! static void write_bare_function_type PARAMS ((tree, int, tree));
! static void write_method_parms PARAMS ((tree, int, tree));
  static void write_class_enum_type PARAMS ((tree));
  static void write_template_args PARAMS ((tree));
  static void write_expression PARAMS ((tree));
*************** write_encoding (decl)
*** 653,659 ****
  				(!DECL_CONSTRUCTOR_P (decl)
  				 && !DECL_DESTRUCTOR_P (decl)
  				 && !DECL_CONV_FN_P (decl)
! 				 && decl_is_template_id (decl, NULL)));
      }
  }
  
--- 653,660 ----
  				(!DECL_CONSTRUCTOR_P (decl)
  				 && !DECL_DESTRUCTOR_P (decl)
  				 && !DECL_CONV_FN_P (decl)
! 				 && decl_is_template_id (decl, NULL)),
! 				decl);
      }
  }
  
*************** write_function_type (type)
*** 1530,1549 ****
         extern "C" function_t f; // Vice versa.
  
       See [dcl.link].  */
!   write_bare_function_type (type, /*include_return_type_p=*/1);
    write_char ('E');
  }
  
! /* Non-terminal <bare-function-type>.  NODE is a FUNCTION_DECL or a
     METHOD_TYPE.  If INCLUDE_RETURN_TYPE is non-zero, the return value
!    is mangled before the parameter types.
  
       <bare-function-type> ::= </signature/ type>+  */
  
  static void
! write_bare_function_type (type, include_return_type_p)
       tree type;
       int include_return_type_p;
  {
    MANGLE_TRACE_TREE ("bare-function-type", type);
  
--- 1531,1553 ----
         extern "C" function_t f; // Vice versa.
  
       See [dcl.link].  */
!   write_bare_function_type (type, /*include_return_type_p=*/1, 
! 			    /*decl=*/NULL);
    write_char ('E');
  }
  
! /* Non-terminal <bare-function-type>.  TYPE is a FUNCTION_TYPE or
     METHOD_TYPE.  If INCLUDE_RETURN_TYPE is non-zero, the return value
!    is mangled before the parameter types.  If non-NULL, DECL is
!    FUNCTION_DECL for the function whose type is being emitted.
  
       <bare-function-type> ::= </signature/ type>+  */
  
  static void
! write_bare_function_type (type, include_return_type_p, decl)
       tree type;
       int include_return_type_p;
+      tree decl;
  {
    MANGLE_TRACE_TREE ("bare-function-type", type);
  
*************** write_bare_function_type (type, include_
*** 1553,1571 ****
  
    /* Now mangle the types of the arguments.  */
    write_method_parms (TYPE_ARG_TYPES (type), 
! 		      TREE_CODE (type) == METHOD_TYPE);
  }
  
  /* Write the mangled representation of a method parameter list of
!    types given in PARM_LIST.  If METHOD_P is non-zero, the function is 
!    considered a non-static method, and the this parameter is omitted.  */
  
  static void
! write_method_parms (parm_list, method_p)
!      tree parm_list;
       int method_p;
  {
!   tree first_parm;
    /* Assume this parameter type list is variable-length.  If it ends
       with a void type, then it's not.  */
    int varargs_p = 1;
--- 1557,1581 ----
  
    /* Now mangle the types of the arguments.  */
    write_method_parms (TYPE_ARG_TYPES (type), 
! 		      TREE_CODE (type) == METHOD_TYPE,
! 		      decl);
  }
  
  /* Write the mangled representation of a method parameter list of
!    types given in PARM_TYPES.  If METHOD_P is non-zero, the function is 
!    considered a non-static method, and the this parameter is omitted.
!    If non-NULL, DECL is the FUNCTION_DECL for the function whose
!    parameters are being emitted.  */
  
  static void
! write_method_parms (parm_types, method_p, decl)
!      tree decl;
!      tree parm_types;
       int method_p;
  {
!   tree first_parm_type;
!   tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;
! 
    /* Assume this parameter type list is variable-length.  If it ends
       with a void type, then it's not.  */
    int varargs_p = 1;
*************** write_method_parms (parm_list, method_p)
*** 1573,1600 ****
    /* If this is a member function, skip the first arg, which is the
       this pointer.  
         "Member functions do not encode the type of their implicit this
!        parameter."  */
    if (method_p)
-     parm_list = TREE_CHAIN (parm_list);
- 
-   for (first_parm = parm_list; 
-        parm_list; 
-        parm_list = TREE_CHAIN (parm_list))
      {
!       tree parm = TREE_VALUE (parm_list);
  
        if (parm == void_type_node)
  	{
  	  /* "Empty parameter lists, whether declared as () or
  	     conventionally as (void), are encoded with a void parameter
  	     (v)."  */
! 	  if (parm_list == first_parm)
  	    write_type (parm);
  	  /* If the parm list is terminated with a void type, it's
  	     fixed-length.  */
  	  varargs_p = 0;
  	  /* A void type better be the last one.  */
! 	  my_friendly_assert (TREE_CHAIN (parm_list) == NULL, 20000523);
  	}
        else
  	write_type (parm);
--- 1583,1621 ----
    /* If this is a member function, skip the first arg, which is the
       this pointer.  
         "Member functions do not encode the type of their implicit this
!        parameter."  
!   
!      Similarly, there's no need to mangle artificial parameters, like
!      the VTT parameters for constructors and destructors.  */
    if (method_p)
      {
!       parm_types = TREE_CHAIN (parm_types);
!       parm_decl = parm_decl ? TREE_CHAIN (parm_decl) : NULL_TREE;
  
+       while (parm_decl && DECL_ARTIFICIAL (parm_decl))
+ 	{
+ 	  parm_types = TREE_CHAIN (parm_types);
+ 	  parm_decl = TREE_CHAIN (parm_decl);
+ 	}
+     }
+ 
+   for (first_parm_type = parm_types; 
+        parm_types; 
+        parm_types = TREE_CHAIN (parm_types))
+     {
+       tree parm = TREE_VALUE (parm_types);
        if (parm == void_type_node)
  	{
  	  /* "Empty parameter lists, whether declared as () or
  	     conventionally as (void), are encoded with a void parameter
  	     (v)."  */
! 	  if (parm_types == first_parm_type)
  	    write_type (parm);
  	  /* If the parm list is terminated with a void type, it's
  	     fixed-length.  */
  	  varargs_p = 0;
  	  /* A void type better be the last one.  */
! 	  my_friendly_assert (TREE_CHAIN (parm_types) == NULL, 20000523);
  	}
        else
  	write_type (parm);


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