From c3e899c1259f0117a62069c1edbbad41ef1b36ec Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 15 Dec 2000 10:43:11 -0500 Subject: [PATCH] call.c (build_op_delete_call): See through ARRAY_TYPEs. * call.c (build_op_delete_call): See through ARRAY_TYPEs. * call.c (build_new_function_call): Lose space before paren in error message. (build_new_method_call): Likewise. * typeck2.c (build_m_component_ref): Propagate quals from datum. From-SVN: r38287 --- gcc/cp/ChangeLog | 10 ++++++ gcc/cp/call.c | 14 ++++---- gcc/cp/typeck2.c | 35 ++++++++++++++----- .../g++.old-deja/g++.other/delete7.C | 17 +++++++++ .../g++.old-deja/g++.other/ptrmem9.C | 18 ++++++++++ 5 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/delete7.C create mode 100644 gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 07753bf4149..a13baaa1d55 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2000-12-15 Jason Merrill + + * call.c (build_op_delete_call): See through ARRAY_TYPEs. + + * call.c (build_new_function_call): Lose space before paren in + error message. + (build_new_method_call): Likewise. + + * typeck2.c (build_m_component_ref): Propagate quals from datum. + 2000-12-14 Kriang Lerdsuwanakij * pt.c (check_explicit_specialization): Propagate default diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2f8a9dc7ed6..77e29ebe354 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2576,7 +2576,7 @@ build_new_function_call (fn, args) { if (candidates && ! candidates->next) return build_function_call (candidates->fn, args); - cp_error ("no matching function for call to `%D (%A)'", + cp_error ("no matching function for call to `%D(%A)'", DECL_NAME (OVL_FUNCTION (fn)), args); if (candidates) print_z_candidates (candidates); @@ -2587,7 +2587,7 @@ build_new_function_call (fn, args) if (cand == 0) { - cp_error ("call of overloaded `%D (%A)' is ambiguous", + cp_error ("call of overloaded `%D(%A)' is ambiguous", DECL_NAME (OVL_FUNCTION (fn)), args); print_z_candidates (candidates); return error_mark_node; @@ -3322,7 +3322,7 @@ build_new_op (code, flags, arg1, arg2, arg3) /* Look for an `operator++ (int)'. If they didn't have one, then we fall back to the old way of doing things. */ if (flags & LOOKUP_COMPLAIN) - cp_pedwarn ("no `%D (int)' declared for postfix `%s', trying prefix operator instead", + cp_pedwarn ("no `%D(int)' declared for postfix `%s', trying prefix operator instead", fnname, operator_name_info[code].name); if (code == POSTINCREMENT_EXPR) @@ -3518,6 +3518,9 @@ build_op_delete_call (code, addr, size, flags, placement) return error_mark_node; type = TREE_TYPE (TREE_TYPE (addr)); + while (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + fnname = ansi_opname (code); if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)) @@ -3562,8 +3565,7 @@ build_op_delete_call (code, addr, size, flags, placement) fntype = build_function_type (void_type_node, argtypes); /* Strip const and volatile from addr. */ - if (type != TYPE_MAIN_VARIANT (type)) - addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr); + addr = cp_convert (ptr_type_node, addr); fn = instantiate_type (fntype, fns, itf_no_attributes); @@ -4447,7 +4449,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) if (!COMPLETE_TYPE_P (basetype)) incomplete_type_error (instance_ptr, basetype); else - cp_error ("no matching function for call to `%T::%D (%A)%V'", + cp_error ("no matching function for call to `%T::%D(%A)%V'", basetype, pretty_name, user_args, TREE_TYPE (TREE_TYPE (instance_ptr))); print_z_candidates (candidates); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 60933e385d3..d8143f88b9b 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1077,22 +1077,26 @@ build_m_component_ref (datum, component) tree datum, component; { tree type; - tree objtype = TREE_TYPE (datum); - tree rettype; + tree objtype; + tree field_type; + int type_quals; tree binfo; if (processing_template_decl) return build_min_nt (DOTSTAR_EXPR, datum, component); + datum = decay_conversion (datum); + objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum)); + if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component))) { type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component))); - rettype = type; + field_type = type; } else { type = TREE_TYPE (TREE_TYPE (component)); - rettype = TREE_TYPE (type); + field_type = TREE_TYPE (type); } if (datum == error_mark_node || component == error_mark_node) @@ -1104,10 +1108,6 @@ build_m_component_ref (datum, component) return error_mark_node; } - if (TREE_CODE (objtype) == REFERENCE_TYPE) - objtype = TREE_TYPE (objtype); - objtype = TYPE_MAIN_VARIANT (objtype); - if (! IS_AGGR_TYPE (objtype)) { cp_error ("cannot apply member pointer `%E' to `%E'", component, datum); @@ -1125,7 +1125,24 @@ build_m_component_ref (datum, component) else if (binfo == error_mark_node) return error_mark_node; - component = build (OFFSET_REF, rettype, datum, component); + /* Compute the type of the field, as described in [expr.ref]. */ + type_quals = TYPE_UNQUALIFIED; + if (TREE_CODE (field_type) == REFERENCE_TYPE) + /* The standard says that the type of the result should be the + type referred to by the reference. But for now, at least, we + do the conversion from reference type later. */ + ; + else + { + type_quals = (CP_TYPE_QUALS (field_type) + | CP_TYPE_QUALS (TREE_TYPE (datum))); + + /* There's no such thing as a mutable pointer-to-member, so we don't + need to deal with that here like we do in build_component_ref. */ + field_type = cp_build_qualified_type (field_type, type_quals); + } + + component = build (OFFSET_REF, field_type, datum, component); if (TREE_CODE (type) == OFFSET_TYPE) component = resolve_offset_ref (component); return component; diff --git a/gcc/testsuite/g++.old-deja/g++.other/delete7.C b/gcc/testsuite/g++.old-deja/g++.other/delete7.C new file mode 100644 index 00000000000..e6c58cd6753 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/delete7.C @@ -0,0 +1,17 @@ +// Test that we call a class-specific vector op delete. + +#include + +int r = 1; + +struct A +{ + void operator delete[](void *p) { r = 0; ::operator delete (p); } +}; + +int main () +{ + A (*p)[2] = new A[2][2]; + delete [] p; + return r; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C b/gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C new file mode 100644 index 00000000000..f50ba22d108 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C @@ -0,0 +1,18 @@ +// Test that const-correctness is observed when using pointers-to-members. + +struct A { + int f () { return 1; } + int f () const { return 0; } +}; + +struct B { + A a; + B() { } +}; + +int main () +{ + A B::*bm = &B::a; + const B b; + return (b.*bm).f (); +} -- 2.30.2