+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
{
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);
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;
/* 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)
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))
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);
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);
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)
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);
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;
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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 ();
+}