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
This commit is contained in:
parent
745b909395
commit
c3e899c125
@ -1,3 +1,13 @@
|
||||
2000-12-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* 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 <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
* pt.c (check_explicit_specialization): Propagate default
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
17
gcc/testsuite/g++.old-deja/g++.other/delete7.C
Normal file
17
gcc/testsuite/g++.old-deja/g++.other/delete7.C
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that we call a class-specific vector op delete.
|
||||
|
||||
#include <new>
|
||||
|
||||
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;
|
||||
}
|
18
gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C
Normal file
18
gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C
Normal file
@ -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 ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user