PATCH: C++ PR 8795

Mark Mitchell mark@codesourcery.com
Mon Aug 25 15:49:00 GMT 2003


This patch fixes PR c++/8795, a problem with member functions
returning Altivec types.  The "vector" attribute code ommitted
handling for METHOD_TYPE.  I also moved build_cplus_method_type to the
common code since there's nothing C++-specific about it and it was
needed in this case.

Bootstrapped and tested on i686-pc-linux-gnu, and with a cross
compiler to PowerPC.  Installed on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-08-25  Mark Mitchell  <mark@codesourcery.com>

	PR c++/8795
	* tree.h (build_method_type_directly): Declare.
	* c-common.c (handle_vector_size_attributes): Handle METHOD_TYPEs.
	(vector_size_helper): Likewise.
	* tree.c (build_method_type_directly): New function.
	(build_method_type): Use it.

2003-08-25  Mark Mitchell  <mark@codesourcery.com>

	PR c++/8795
	* cp-tree.h (build_cplus_method_type): Remove.
	* call.c (standard_conversion): Use build_method_type_directly
	instead of build_cplus_method_type.
	* class.c (build_clone): Likewise.
	(adjust_clone_args): Likewise.
	* decl.c (build_ptrmem_type): Likewise.
	(grokdeclarator): Likewise.
	(check_function_type): Likewise.
	* decl2.c (grok_method_quals): Likewise.
	(maybe_retrofit_in_chrg): Likewise.
	* pt.c (copy_default_args_to_explicit_spec): Likewise.
	(tsubst_function_type): Likewise.
	(tsubst): Likewise.
	* tree.c (build_cplus_method_type): Remove.
	* typeck.c (merge_types): Use build_method_type_directly.

2003-08-25  Mark Mitchell  <mark@codesourcery.com>

	PR c++/8795
	* g++.dg/ext/altivec-1.C: New test.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.450
diff -c -5 -p -r1.450 c-common.c
*** c-common.c	20 Aug 2003 22:36:08 -0000	1.450
--- c-common.c	25 Aug 2003 15:44:41 -0000
*************** handle_vector_size_attribute (tree *node
*** 5084,5093 ****
--- 5084,5094 ----
       In this case, the mode is SI, but the type being modified is
       HI, so we need to look further.  */
  
    while (POINTER_TYPE_P (type)
  	 || TREE_CODE (type) == FUNCTION_TYPE
+ 	 || TREE_CODE (type) == METHOD_TYPE
  	 || TREE_CODE (type) == ARRAY_TYPE)
      type = TREE_TYPE (type);
  
    /* Get the mode of the type being modified.  */
    orig_mode = TYPE_MODE (type);
*************** vector_size_helper (tree type, tree bott
*** 5214,5229 ****
        outer = build_pointer_type (inner);
      }
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
        inner = vector_size_helper (TREE_TYPE (type), bottom);
!       outer = build_array_type (inner, TYPE_VALUES (type));
      }
    else if (TREE_CODE (type) == FUNCTION_TYPE)
      {
        inner = vector_size_helper (TREE_TYPE (type), bottom);
!       outer = build_function_type (inner, TYPE_VALUES (type));
      }
    else
      return bottom;
  
    TREE_READONLY (outer) = TREE_READONLY (type);
--- 5215,5237 ----
        outer = build_pointer_type (inner);
      }
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
        inner = vector_size_helper (TREE_TYPE (type), bottom);
!       outer = build_array_type (inner, TYPE_DOMAIN (type));
      }
    else if (TREE_CODE (type) == FUNCTION_TYPE)
      {
        inner = vector_size_helper (TREE_TYPE (type), bottom);
!       outer = build_function_type (inner, TYPE_ARG_TYPES (type));
!     }
!   else if (TREE_CODE (type) == METHOD_TYPE)
!     {
!       inner = vector_size_helper (TREE_TYPE (type), bottom);
!       outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
! 					  inner, 
! 					  TYPE_ARG_TYPES (type));
      }
    else
      return bottom;
  
    TREE_READONLY (outer) = TREE_READONLY (type);
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.325
diff -c -5 -p -r1.325 tree.c
*** tree.c	20 Aug 2003 21:46:46 -0000	1.325
--- tree.c	25 Aug 2003 15:44:42 -0000
*************** build_function_type_list (tree return_ty
*** 3848,3892 ****
  
    va_end (p);
    return args;
  }
  
! /* Construct, lay out and return the type of methods belonging to class
!    BASETYPE and whose arguments and values are described by TYPE.
!    If that type exists already, reuse it.
!    TYPE must be a FUNCTION_TYPE node.  */
  
  tree
! build_method_type (tree basetype, tree type)
  {
    tree t;
!   unsigned int hashcode;
  
    /* Make a node of the sort we want.  */
    t = make_node (METHOD_TYPE);
  
-   if (TREE_CODE (type) != FUNCTION_TYPE)
-     abort ();
- 
    TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
!   TREE_TYPE (t) = TREE_TYPE (type);
  
    /* The actual arglist for this function includes a "hidden" argument
       which is "this".  Put it into the list of argument types.  */
  
!   TYPE_ARG_TYPES (t)
!     = tree_cons (NULL_TREE,
! 		 build_pointer_type (basetype), TYPE_ARG_TYPES (type));
  
-   /* If we already have such a type, use the old one and free this one.  */
-   hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
    t = type_hash_canon (hashcode, t);
  
    if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    return t;
  }
  
  /* Construct, lay out and return the type of offsets to a value
     of type TYPE, within an object of type BASETYPE.
     If a suitable offset type exists already, reuse it.  */
--- 3848,3910 ----
  
    va_end (p);
    return args;
  }
  
! /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
!    and ARGTYPES (a TREE_LIST) are the return type and arguments types
!    for the method.  An implicit additional parameter (of type
!    pointer-to-BASETYPE) is added to the ARGTYPES.  */
  
  tree
! build_method_type_directly (tree basetype,
! 			    tree rettype,
! 			    tree argtypes)
  {
    tree t;
!   tree ptype;
!   int hashcode;
  
    /* Make a node of the sort we want.  */
    t = make_node (METHOD_TYPE);
  
    TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
!   TREE_TYPE (t) = rettype;
!   ptype = build_pointer_type (basetype);
  
    /* The actual arglist for this function includes a "hidden" argument
       which is "this".  Put it into the list of argument types.  */
+   argtypes = tree_cons (NULL_TREE, ptype, argtypes);
+   TYPE_ARG_TYPES (t) = argtypes;
  
!   /* If we already have such a type, use the old one and free this one.
!      Note that it also frees up the above cons cell if found.  */
!   hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
!     type_hash_list (argtypes);
  
    t = type_hash_canon (hashcode, t);
  
    if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    return t;
+ }
+ 
+ /* Construct, lay out and return the type of methods belonging to class
+    BASETYPE and whose arguments and values are described by TYPE.
+    If that type exists already, reuse it.
+    TYPE must be a FUNCTION_TYPE node.  */
+ 
+ tree
+ build_method_type (tree basetype, tree type)
+ {
+   if (TREE_CODE (type) != FUNCTION_TYPE)
+     abort ();
+ 
+   return build_method_type_directly (basetype, 
+ 				     TREE_TYPE (type),
+ 				     TYPE_ARG_TYPES (type));
  }
  
  /* Construct, lay out and return the type of offsets to a value
     of type TYPE, within an object of type BASETYPE.
     If a suitable offset type exists already, reuse it.  */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.438
diff -c -5 -p -r1.438 tree.h
*** tree.h	22 Aug 2003 07:03:15 -0000	1.438
--- tree.h	25 Aug 2003 15:44:42 -0000
*************** extern tree build_type_no_quals (tree);
*** 2105,2114 ****
--- 2105,2115 ----
  extern tree build_index_type (tree);
  extern tree build_index_2_type (tree, tree);
  extern tree build_array_type (tree, tree);
  extern tree build_function_type (tree, tree);
  extern tree build_function_type_list (tree, ...);
+ extern tree build_method_type_directly (tree, tree, tree);
  extern tree build_method_type (tree, tree);
  extern tree build_offset_type (tree, tree);
  extern tree build_complex_type (tree);
  extern tree array_type_nelts (tree);
  
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.423
diff -c -5 -p -r1.423 call.c
*** cp/call.c	21 Aug 2003 22:02:26 -0000	1.423
--- cp/call.c	25 Aug 2003 15:44:43 -0000
*************** standard_conversion (tree to, tree from,
*** 756,767 ****
  			 TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
  	  || cp_type_quals (fbase) != cp_type_quals (tbase))
  	return 0;
  
        from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
!       from = build_cplus_method_type (from, TREE_TYPE (fromfn),
! 				      TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
        from = build_ptrmemfunc_type (build_pointer_type (from));
        conv = build_conv (PMEM_CONV, from, conv);
      }
    else if (tcode == BOOLEAN_TYPE)
      {
--- 756,768 ----
  			 TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
  	  || cp_type_quals (fbase) != cp_type_quals (tbase))
  	return 0;
  
        from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
!       from = build_method_type_directly (from, 
! 					 TREE_TYPE (fromfn),
! 					 TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
        from = build_ptrmemfunc_type (build_pointer_type (from));
        conv = build_conv (PMEM_CONV, from, conv);
      }
    else if (tcode == BOOLEAN_TYPE)
      {
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.564
diff -c -5 -p -r1.564 class.c
*** cp/class.c	20 Aug 2003 07:06:40 -0000	1.564
--- cp/class.c	25 Aug 2003 15:44:43 -0000
*************** build_clone (tree fn, tree name)
*** 3831,3843 ****
  	  && ! DECL_NEEDS_VTT_PARM_P (clone))
  	parmtypes = TREE_CHAIN (parmtypes);
         /* If this is subobject constructor or destructor, add the vtt
  	 parameter.  */
        TREE_TYPE (clone) 
! 	= build_cplus_method_type (basetype,
! 				   TREE_TYPE (TREE_TYPE (clone)),
! 				   parmtypes);
        if (exceptions)
  	TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
  						     exceptions);
      }
  
--- 3831,3843 ----
  	  && ! DECL_NEEDS_VTT_PARM_P (clone))
  	parmtypes = TREE_CHAIN (parmtypes);
         /* If this is subobject constructor or destructor, add the vtt
  	 parameter.  */
        TREE_TYPE (clone) 
! 	= build_method_type_directly (basetype,
! 				      TREE_TYPE (TREE_TYPE (clone)),
! 				      parmtypes);
        if (exceptions)
  	TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
  						     exceptions);
      }
  
*************** adjust_clone_args (tree decl)
*** 4010,4022 ****
  		  clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
  					   TREE_VALUE (orig_clone_parms),
  					   clone_parms);
  		  TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
  		}
! 	      type = build_cplus_method_type (basetype,
! 					      TREE_TYPE (TREE_TYPE (clone)),
! 					      clone_parms);
  	      if (exceptions)
  		type = build_exception_variant (type, exceptions);
  	      TREE_TYPE (clone) = type;
  	      
  	      clone_parms = NULL_TREE;
--- 4010,4022 ----
  		  clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
  					   TREE_VALUE (orig_clone_parms),
  					   clone_parms);
  		  TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
  		}
! 	      type = build_method_type_directly (basetype,
! 						 TREE_TYPE (TREE_TYPE (clone)),
! 						 clone_parms);
  	      if (exceptions)
  		type = build_exception_variant (type, exceptions);
  	      TREE_TYPE (clone) = type;
  	      
  	      clone_parms = NULL_TREE;
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.906
diff -c -5 -p -r1.906 cp-tree.h
*** cp/cp-tree.h	23 Aug 2003 12:53:45 -0000	1.906
--- cp/cp-tree.h	25 Aug 2003 15:44:44 -0000
*************** extern int non_cast_lvalue_or_else		(tre
*** 4168,4178 ****
  extern tree build_min				(enum tree_code, tree,
  							 ...);
  extern tree build_min_nt			(enum tree_code, ...);
  extern tree build_cplus_new			(tree, tree);
  extern tree get_target_expr			(tree);
- extern tree build_cplus_method_type		(tree, tree, tree);
  extern tree build_cplus_staticfn_type		(tree, tree, tree);
  extern tree build_cplus_array_type		(tree, tree);
  extern tree hash_tree_cons			(tree, tree, tree);
  extern tree hash_tree_chain			(tree, tree);
  extern tree hash_chainon			(tree, tree);
--- 4168,4177 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1116
diff -c -5 -p -r1.1116 decl.c
*** cp/decl.c	23 Aug 2003 12:53:45 -0000	1.1116
--- cp/decl.c	25 Aug 2003 15:44:44 -0000
*************** build_ptrmem_type (tree class_type, tree
*** 9257,9269 ****
        arg_types = TYPE_ARG_TYPES (member_type);
        class_type = (cp_build_qualified_type 
  		    (class_type,
  		     cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
        member_type 
! 	= build_cplus_method_type (class_type, 
! 				   TREE_TYPE (member_type),
! 				   TREE_CHAIN (arg_types));
        return build_ptrmemfunc_type (build_pointer_type (member_type));
      }
    else
      {
        my_friendly_assert (TREE_CODE (member_type) != FUNCTION_TYPE,
--- 9257,9269 ----
        arg_types = TYPE_ARG_TYPES (member_type);
        class_type = (cp_build_qualified_type 
  		    (class_type,
  		     cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
        member_type 
! 	= build_method_type_directly (class_type, 
! 				      TREE_TYPE (member_type),
! 				      TREE_CHAIN (arg_types));
        return build_ptrmemfunc_type (build_pointer_type (member_type));
      }
    else
      {
        my_friendly_assert (TREE_CODE (member_type) != FUNCTION_TYPE,
*************** grokdeclarator (tree declarator,
*** 10931,10941 ****
  				  ctype, name);
  		  }
  		else if (TREE_CODE (type) == FUNCTION_TYPE)
  		  {
  		    if (current_class_type == NULL_TREE || friendp)
! 		      type = build_cplus_method_type (ctype, TREE_TYPE (type),
  						      TYPE_ARG_TYPES (type));
  		    else
  		      {
  			error ("cannot declare member function `%T::%s' within `%T'",
  				  ctype, name, current_class_type);
--- 10931,10943 ----
  				  ctype, name);
  		  }
  		else if (TREE_CODE (type) == FUNCTION_TYPE)
  		  {
  		    if (current_class_type == NULL_TREE || friendp)
! 		      type 
! 			= build_method_type_directly (ctype, 
! 						      TREE_TYPE (type),
  						      TYPE_ARG_TYPES (type));
  		    else
  		      {
  			error ("cannot declare member function `%T::%s' within `%T'",
  				  ctype, name, current_class_type);
*************** grokdeclarator (tree declarator,
*** 10973,10984 ****
  		declarator = TREE_OPERAND (declarator, 1);
  		if (declarator && TREE_CODE (declarator) == CALL_EXPR)
  		  /* In this case, we will deal with it later.  */
  		  ;
  		else if (TREE_CODE (type) == FUNCTION_TYPE)
! 		  type = build_cplus_method_type (ctype, TREE_TYPE (type),
! 						  TYPE_ARG_TYPES (type));
  	      }
  	  }
  	  break;
  
  	case BIT_NOT_EXPR:
--- 10975,10987 ----
  		declarator = TREE_OPERAND (declarator, 1);
  		if (declarator && TREE_CODE (declarator) == CALL_EXPR)
  		  /* In this case, we will deal with it later.  */
  		  ;
  		else if (TREE_CODE (type) == FUNCTION_TYPE)
! 		  type = build_method_type_directly (ctype, 
! 						     TREE_TYPE (type),
! 						     TYPE_ARG_TYPES (type));
  	      }
  	  }
  	  break;
  
  	case BIT_NOT_EXPR:
*************** grokdeclarator (tree declarator,
*** 11410,11421 ****
  				  declarator);
  			virtualp = 0;
  		      }
  		  }
  		else if (staticp < 2)
! 		  type = build_cplus_method_type (ctype, TREE_TYPE (type),
! 						  TYPE_ARG_TYPES (type));
  	      }
  
  	    /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
  	    function_context = (ctype != NULL_TREE) ?
  	      decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
--- 11413,11425 ----
  				  declarator);
  			virtualp = 0;
  		      }
  		  }
  		else if (staticp < 2)
! 		  type = build_method_type_directly (ctype, 
! 						     TREE_TYPE (type),
! 						     TYPE_ARG_TYPES (type));
  	      }
  
  	    /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
  	    function_context = (ctype != NULL_TREE) ?
  	      decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
*************** grokdeclarator (tree declarator,
*** 11647,11658 ****
  		error ("virtual non-class function `%s'", name);
  		virtualp = 0;
  	      }
  	  }
  	else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)
! 	  type = build_cplus_method_type (ctype, TREE_TYPE (type),
! 					  TYPE_ARG_TYPES (type));
  
  	/* Record presence of `static'.  */
  	publicp = (ctype != NULL_TREE
  		   || RIDBIT_SETP (RID_EXTERN, specbits)
  		   || !RIDBIT_SETP (RID_STATIC, specbits));
--- 11651,11663 ----
  		error ("virtual non-class function `%s'", name);
  		virtualp = 0;
  	      }
  	  }
  	else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)
! 	  type = build_method_type_directly (ctype, 
! 					     TREE_TYPE (type),
! 					     TYPE_ARG_TYPES (type));
  
  	/* Record presence of `static'.  */
  	publicp = (ctype != NULL_TREE
  		   || RIDBIT_SETP (RID_EXTERN, specbits)
  		   || !RIDBIT_SETP (RID_STATIC, specbits));
*************** check_function_type (tree decl, tree cur
*** 13315,13327 ****
  	 type of the DECL_RESULT, in case we have a named return value.  */
        if (TREE_CODE (fntype) == METHOD_TYPE)
  	{
  	  tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)));
  	  TREE_TYPE (decl)
! 	    = build_cplus_method_type (ctype,
! 				       void_type_node,
! 				       FUNCTION_ARG_CHAIN (decl));
  	}
        else
  	TREE_TYPE (decl)
  	  = build_function_type (void_type_node,
  				 TYPE_ARG_TYPES (TREE_TYPE (decl)));
--- 13320,13332 ----
  	 type of the DECL_RESULT, in case we have a named return value.  */
        if (TREE_CODE (fntype) == METHOD_TYPE)
  	{
  	  tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)));
  	  TREE_TYPE (decl)
! 	    = build_method_type_directly (ctype,
! 					  void_type_node,
! 					  FUNCTION_ARG_CHAIN (decl));
  	}
        else
  	TREE_TYPE (decl)
  	  = build_function_type (void_type_node,
  				 TYPE_ARG_TYPES (TREE_TYPE (decl)));
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.663
diff -c -5 -p -r1.663 decl2.c
*** cp/decl2.c	21 Aug 2003 17:44:15 -0000	1.663
--- cp/decl2.c	25 Aug 2003 15:44:45 -0000
*************** grok_method_quals (tree ctype, tree func
*** 152,165 ****
      error ("duplicate type qualifiers in %s declaration",
  	      TREE_CODE (function) == FUNCTION_DECL 
  	      ? "member function" : "type");
  
    ctype = cp_build_qualified_type (ctype, type_quals);
!   fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),
! 				    (TREE_CODE (fntype) == METHOD_TYPE
! 				     ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
! 				     : TYPE_ARG_TYPES (fntype)));
    if (raises)
      fntype = build_exception_variant (fntype, raises);
  
    TREE_TYPE (function) = fntype;
    return this_quals;
--- 152,165 ----
      error ("duplicate type qualifiers in %s declaration",
  	      TREE_CODE (function) == FUNCTION_DECL 
  	      ? "member function" : "type");
  
    ctype = cp_build_qualified_type (ctype, type_quals);
!   fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
! 				       (TREE_CODE (fntype) == METHOD_TYPE
! 					? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
! 					: TYPE_ARG_TYPES (fntype)));
    if (raises)
      fntype = build_exception_variant (fntype, raises);
  
    TREE_TYPE (function) = fntype;
    return this_quals;
*************** maybe_retrofit_in_chrg (tree fn)
*** 307,318 ****
  
    /* Insert our new parameter(s) into the list.  */
    TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
  
    /* And rebuild the function type.  */
!   fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
! 				    arg_types);
    if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
      fntype = build_exception_variant (fntype,
  				      TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
    TREE_TYPE (fn) = fntype;
  
--- 307,318 ----
  
    /* Insert our new parameter(s) into the list.  */
    TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
  
    /* And rebuild the function type.  */
!   fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)),
! 				       arg_types);
    if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
      fntype = build_exception_variant (fntype,
  				      TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
    TREE_TYPE (fn) = fntype;
  
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.764
diff -c -5 -p -r1.764 pt.c
*** cp/pt.c	23 Aug 2003 12:53:46 -0000	1.764
--- cp/pt.c	25 Aug 2003 15:44:45 -0000
*************** copy_default_args_to_explicit_spec (tree
*** 1380,1392 ****
          /* Put the in-charge parameter back.  */
          new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
  			  	         TREE_VALUE (in_charge),
  				         new_spec_types);
  
!       new_type = build_cplus_method_type (object_type,
! 					  TREE_TYPE (old_type),
! 					  new_spec_types);
      }
    else
      new_type = build_function_type (TREE_TYPE (old_type),
  				    new_spec_types);
    new_type = build_type_attribute_variant (new_type,
--- 1380,1392 ----
          /* Put the in-charge parameter back.  */
          new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
  			  	         TREE_VALUE (in_charge),
  				         new_spec_types);
  
!       new_type = build_method_type_directly (object_type,
! 					     TREE_TYPE (old_type),
! 					     new_spec_types);
      }
    else
      new_type = build_function_type (TREE_TYPE (old_type),
  				    new_spec_types);
    new_type = build_type_attribute_variant (new_type,
*************** tsubst_function_type (tree t, 
*** 6291,6302 ****
  	    error ("creating pointer to member function of non-class type `%T'",
  		      r);
  	  return error_mark_node;
  	}
        
!       fntype = build_cplus_method_type (r, return_type, TREE_CHAIN
! 					(arg_types));
      }
    fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
    fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
    
    return fntype;  
--- 6291,6302 ----
  	    error ("creating pointer to member function of non-class type `%T'",
  		      r);
  	  return error_mark_node;
  	}
        
!       fntype = build_method_type_directly (r, return_type, 
! 					   TREE_CHAIN (arg_types));
      }
    fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
    fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
    
    return fntype;  
*************** tsubst (tree t, tree args, tsubst_flags_
*** 6759,6771 ****
  		  template <typename T1> void Foo (Func T1::*);
  
  		*/
  	    tree method_type;
  
! 	    method_type = build_cplus_method_type (TYPE_MAIN_VARIANT (r),
! 						   TREE_TYPE (type),
! 						   TYPE_ARG_TYPES (type));
  	    return build_ptrmemfunc_type (build_pointer_type (method_type));
  	  }
  	else
  	  return cp_build_qualified_type_real (build_ptrmem_type (r, type),
  					       TYPE_QUALS (t),
--- 6759,6771 ----
  		  template <typename T1> void Foo (Func T1::*);
  
  		*/
  	    tree method_type;
  
! 	    method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r),
! 						      TREE_TYPE (type),
! 						      TYPE_ARG_TYPES (type));
  	    return build_ptrmemfunc_type (build_pointer_type (method_type));
  	  }
  	else
  	  return cp_build_qualified_type_real (build_ptrmem_type (r, type),
  					       TYPE_QUALS (t),
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.341
diff -c -5 -p -r1.341 tree.c
*** cp/tree.c	21 Aug 2003 03:20:54 -0000	1.341
--- cp/tree.c	25 Aug 2003 15:44:45 -0000
*************** get_target_expr (tree init)
*** 371,417 ****
  {
    return build_target_expr_with_type (init, TREE_TYPE (init));
  }
  
  
- /* Construct, lay out and return the type of methods belonging to class
-    BASETYPE and whose arguments are described by ARGTYPES and whose values
-    are described by RETTYPE.  If each type exists already, reuse it.  */
- 
- tree
- build_cplus_method_type (tree basetype, tree rettype, tree argtypes)
- {
-   register tree t;
-   tree ptype;
-   int hashcode;
- 
-   /* Make a node of the sort we want.  */
-   t = make_node (METHOD_TYPE);
- 
-   TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
-   TREE_TYPE (t) = rettype;
-   ptype = build_pointer_type (basetype);
- 
-   /* The actual arglist for this function includes a "hidden" argument
-      which is "this".  Put it into the list of argument types.  */
-   argtypes = tree_cons (NULL_TREE, ptype, argtypes);
-   TYPE_ARG_TYPES (t) = argtypes;
-   TREE_SIDE_EFFECTS (argtypes) = 1;  /* Mark first argtype as "artificial".  */
- 
-   /* If we already have such a type, use the old one and free this one.
-      Note that it also frees up the above cons cell if found.  */
-   hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
-     type_hash_list (argtypes);
- 
-   t = type_hash_canon (hashcode, t);
- 
-   if (!COMPLETE_TYPE_P (t))
-     layout_type (t);
- 
-   return t;
- }
- 
  static tree
  build_cplus_array_type_1 (tree elt_type, tree index_type)
  {
    tree t;
  
--- 371,380 ----
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.494
diff -c -5 -p -r1.494 typeck.c
*** cp/typeck.c	20 Aug 2003 18:00:08 -0000	1.494
--- cp/typeck.c	25 Aug 2003 15:44:45 -0000
*************** merge_types (tree t1, tree t2)
*** 706,717 ****
  	t1 = build_function_type (TREE_TYPE (t1),
  				  TREE_CHAIN (TYPE_ARG_TYPES (t1)));
  	t2 = build_function_type (TREE_TYPE (t2),
  				  TREE_CHAIN (TYPE_ARG_TYPES (t2)));
  	t3 = merge_types (t1, t2);
! 	t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
! 				      TYPE_ARG_TYPES (t3));
  	t1 = build_exception_variant (t3, raises);
  	break;
        }
  
      default:;
--- 706,717 ----
  	t1 = build_function_type (TREE_TYPE (t1),
  				  TREE_CHAIN (TYPE_ARG_TYPES (t1)));
  	t2 = build_function_type (TREE_TYPE (t2),
  				  TREE_CHAIN (TYPE_ARG_TYPES (t2)));
  	t3 = merge_types (t1, t2);
! 	t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
! 					 TYPE_ARG_TYPES (t3));
  	t1 = build_exception_variant (t3, raises);
  	break;
        }
  
      default:;
Index: testsuite/g++.dg/ext/altivec-1.C
===================================================================
RCS file: testsuite/g++.dg/ext/altivec-1.C
diff -N testsuite/g++.dg/ext/altivec-1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/altivec-1.C	25 Aug 2003 15:44:46 -0000
***************
*** 0 ****
--- 1,15 ----
+ // { dg-do compile { target powerpc-*-* } } */
+ /* { dg-options "-maltivec" } */
+ 
+ #include <altivec.h>
+  
+ int main()
+ {
+   return 0;
+ }
+ 
+ class F32vec4 {
+ public:
+   vector float val;
+   vector float operator++(void) { return val;}
+ };
Index: testsuite/g++.dg/ext/cond1.C
===================================================================
RCS file: testsuite/g++.dg/ext/cond1.C
diff -N testsuite/g++.dg/ext/cond1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/cond1.C	25 Aug 2003 15:44:46 -0000
***************
*** 0 ****
--- 1,10 ----
+ // { dg-options "" }
+ 
+ template<int X> class c;
+ 
+ template<int X, int Y> int test(c<X ? : Y>&);
+ 
+ void test(c<2>*c2) {
+ 	test<0, 2>(*c2);
+ }
+ 
Index: testsuite/g++.dg/opt/ptrmem3.C
===================================================================
RCS file: testsuite/g++.dg/opt/ptrmem3.C
diff -N testsuite/g++.dg/opt/ptrmem3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/opt/ptrmem3.C	25 Aug 2003 15:44:46 -0000
***************
*** 0 ****
--- 1,23 ----
+ // { dg-options "-O1" }
+ 
+ #include <stdio.h>
+ struct A {
+      A(int arg) : ia(arg) {}
+      int x,y,z,ia;
+      int mf(int arg) { return arg + ia; }
+ };
+ int func(int A::*pdm, int (A::*pmf)(int)) //      2.      regular function
+ { 
+      A oa(2);
+      return ((&oa)->*pdm) + (oa.*pmf)(2); 
+ }       
+ int main()
+ {
+      int val;
+ 
+      int A::*pda = &A::ia;           
+      int (A::*pmfa)(int) = &A::mf;   
+      val = func( pda, pmfa );
+      if(val != 6)
+        printf("val=%d, expect 6 \n", val);
+ }



More information about the Gcc-patches mailing list