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