OSDN Git Service

* call.c (build_op_delete_call): See through ARRAY_TYPEs.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Dec 2000 15:43:11 +0000 (15:43 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Dec 2000 15:43:11 +0000 (15:43 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38287 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck2.c
gcc/testsuite/g++.old-deja/g++.other/delete7.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/ptrmem9.C [new file with mode: 0644]

index 07753bf..a13baaa 100644 (file)
@@ -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
index 2f8a9dc..77e29eb 100644 (file)
@@ -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);
index 60933e3..d8143f8 100644 (file)
@@ -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 (file)
index 0000000..e6c58cd
--- /dev/null
@@ -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;
+}
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 (file)
index 0000000..f50ba22
--- /dev/null
@@ -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 ();
+}