OSDN Git Service

PR c++/13113
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Feb 2004 16:53:17 +0000 (16:53 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Feb 2004 16:53:17 +0000 (16:53 +0000)
* init.c (build_offset_ref): Improve error recovery for invalid
uses of non-static member functions.

PR c++/13854
* cp-tree.h (cp_build_type_attribute_variant): New function.
* class.c (build_clone): Use cp_build_type_attribute_variant.
* decl.c (duplicate_decls): Likewise.
* pt.c (copy_default_args_to_explicit_spec): Likewise.
(tsubst_function_type): Likewise.
* tree.c (build_exception_variant): Check attributes before
concluding that two types are the same.
(cp_build_type-attribute_variant): New method.
* typeck.c (merge_types): Use cp_build_type_attribute_variant.

PR c++/13907
* call.c (convert_class_to_reference): Keep better track of
pedantically invalid user-defined conversions.

PR c++/13113
* g++.old-deja/g++.mike/net36.C: Adjust error messages.

PR c++/13854
* g++.dg/ext/attrib13.C: New test.

PR c++/13907
* g++.dg/conversion/op2.C: New test.

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

13 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/op2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attrib13.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.mike/net36.C

index ed2a83f..9c3d573 100644 (file)
@@ -1,3 +1,24 @@
+2004-02-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/13113
+       * init.c (build_offset_ref): Improve error recovery for invalid
+       uses of non-static member functions.
+
+       PR c++/13854
+       * cp-tree.h (cp_build_type_attribute_variant): New function.
+       * class.c (build_clone): Use cp_build_type_attribute_variant.
+       * decl.c (duplicate_decls): Likewise.
+       * pt.c (copy_default_args_to_explicit_spec): Likewise.
+       (tsubst_function_type): Likewise.
+       * tree.c (build_exception_variant): Check attributes before
+       concluding that two types are the same.
+       (cp_build_type-attribute_variant): New method.
+       * typeck.c (merge_types): Use cp_build_type_attribute_variant.
+
+       PR c++/13907
+       * call.c (convert_class_to_reference): Keep better track of
+       pedantically invalid user-defined conversions.
+
 2004-02-01  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        PR c++/13957
index d391b29..0aa19f1 100644 (file)
@@ -828,15 +828,19 @@ convert_class_to_reference (tree t, tree s, tree expr)
                                           LOOKUP_NORMAL);
          
          if (cand)
-           /* Build a standard conversion sequence indicating the
-              binding from the reference type returned by the
-              function to the desired REFERENCE_TYPE.  */
-           cand->second_conv
-             = (direct_reference_binding 
-                (reference_type, 
-                 build1 (IDENTITY_CONV, 
-                         TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
-                         NULL_TREE)));
+           {
+             /* Build a standard conversion sequence indicating the
+                binding from the reference type returned by the
+                function to the desired REFERENCE_TYPE.  */
+             cand->second_conv
+               = (direct_reference_binding 
+                  (reference_type, 
+                   build1 (IDENTITY_CONV, 
+                           TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+                           NULL_TREE)));
+             ICS_BAD_FLAG (cand->second_conv) 
+               |= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));
+           }
        }
       conversions = TREE_CHAIN (conversions);
     }
index 23ca83d..96e48e4 100644 (file)
@@ -3873,8 +3873,8 @@ build_clone (tree fn, tree name)
        TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
                                                     exceptions);
       TREE_TYPE (clone) 
-       = build_type_attribute_variant (TREE_TYPE (clone),
-                                       TYPE_ATTRIBUTES (TREE_TYPE (fn)));
+       = cp_build_type_attribute_variant (TREE_TYPE (clone),
+                                          TYPE_ATTRIBUTES (TREE_TYPE (fn)));
     }
 
   /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
index 0614d72..5e64578 100644 (file)
@@ -4154,6 +4154,7 @@ extern tree maybe_dummy_object                    (tree, tree *);
 extern int is_dummy_object                     (tree);
 extern const struct attribute_spec cxx_attribute_table[];
 extern tree make_ptrmem_cst                     (tree, tree);
+extern tree cp_build_type_attribute_variant     (tree, tree);
 extern tree cp_build_qualified_type_real        (tree, int, tsubst_flags_t);
 #define cp_build_qualified_type(TYPE, QUALS) \
   cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
index a9e0316..c949c74 100644 (file)
@@ -1266,7 +1266,7 @@ duplicate_decls (tree newdecl, tree olddecl)
          tree attribs = (*targetm.merge_type_attributes)
            (TREE_TYPE (olddecl), type);
 
-         type = build_type_attribute_variant (type, attribs);
+         type = cp_build_type_attribute_variant (type, attribs);
          TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
        }
 
index 6f361b0..2c89996 100644 (file)
@@ -1559,16 +1559,20 @@ build_offset_ref (tree type, tree name, bool address_p)
           a class derived from that class (_class.base.init_).  */
       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
        {
+         /* Build a representation of a the qualified name suitable
+            for use as the operand to "&" -- even though the "&" is
+            not actually present.  */
+         member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
          /* In Microsoft mode, treat a non-static member function as if
             it were a pointer-to-member.  */
          if (flag_ms_extensions)
            {
-             member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
              PTRMEM_OK_P (member) = 1;
              return build_unary_op (ADDR_EXPR, member, 0);
            }
-         error ("invalid use of non-static member function `%D'", member);
-         return error_mark_node;
+         error ("invalid use of non-static member function `%D'", 
+                TREE_OPERAND (member, 1));
+         return member;
        }
       else if (TREE_CODE (member) == FIELD_DECL)
        {
index 90455bc..f035042 100644 (file)
@@ -1526,8 +1526,8 @@ copy_default_args_to_explicit_spec (tree decl)
   else
     new_type = build_function_type (TREE_TYPE (old_type),
                                    new_spec_types);
-  new_type = build_type_attribute_variant (new_type,
-                                          TYPE_ATTRIBUTES (old_type));
+  new_type = cp_build_type_attribute_variant (new_type,
+                                             TYPE_ATTRIBUTES (old_type));
   new_type = build_exception_variant (new_type,
                                      TYPE_RAISES_EXCEPTIONS (old_type));
   TREE_TYPE (decl) = new_type;
@@ -6476,7 +6476,7 @@ tsubst_function_type (tree t,
                                           TREE_CHAIN (arg_types));
     }
   fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
-  fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
+  fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
   
   return fntype;  
 }
index 7d98128..3413ede 100644 (file)
@@ -991,7 +991,8 @@ build_exception_variant (tree type, tree raises)
 
   for (; v; v = TYPE_NEXT_VARIANT (v))
     if (TYPE_QUALS (v) == type_quals
-        && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1))
+        && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)
+       && (*targetm.comp_type_attributes) (type, v))
       return v;
 
   /* Need to build a new variant.  */
@@ -1962,6 +1963,23 @@ make_ptrmem_cst (tree type, tree member)
   return ptrmem_cst;
 }
 
+/* Build a variant of TYPE that has the indicated ATTRIBUTES.  May
+   return an existing type of an appropriate type already exists.  */
+
+tree
+cp_build_type_attribute_variant (tree type, tree attributes)
+{
+  tree new_type;
+
+  new_type = build_type_attribute_variant (type, attributes);
+  if (TREE_CODE (new_type) == FUNCTION_TYPE
+      && (TYPE_RAISES_EXCEPTIONS (new_type) 
+         != TYPE_RAISES_EXCEPTIONS (type)))
+    new_type = build_exception_variant (new_type,
+                                       TYPE_RAISES_EXCEPTIONS (type));
+  return new_type;
+}
+
 /* Apply FUNC to all language-specific sub-trees of TP in a pre-order
    traversal.  Called from walk_tree().  */
 
index 1338085..4f635cc 100644 (file)
@@ -666,9 +666,9 @@ merge_types (tree t1, tree t2)
 
        /* Save space: see if the result is identical to one of the args.  */
        if (valtype == TREE_TYPE (t1) && ! p2)
-         return build_type_attribute_variant (t1, attributes);
+         return cp_build_type_attribute_variant (t1, attributes);
        if (valtype == TREE_TYPE (t2) && ! p1)
-         return build_type_attribute_variant (t2, attributes);
+         return cp_build_type_attribute_variant (t2, attributes);
 
        /* Simple way if one arg fails to specify argument types.  */
        if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
@@ -676,7 +676,7 @@ merge_types (tree t1, tree t2)
            rval = build_function_type (valtype, p2);
            if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
              rval = build_exception_variant (rval, raises);
-           return build_type_attribute_variant (rval, attributes);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
        raises = TYPE_RAISES_EXCEPTIONS (t1);
        if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
@@ -684,7 +684,7 @@ merge_types (tree t1, tree t2)
            rval = build_function_type (valtype, p1);
            if (raises)
              rval = build_exception_variant (rval, raises);
-           return build_type_attribute_variant (rval, attributes);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
 
        rval = build_function_type (valtype, commonparms (p1, p2));
@@ -722,7 +722,7 @@ merge_types (tree t1, tree t2)
 
     default:;
     }
-  return build_type_attribute_variant (t1, attributes);
+  return cp_build_type_attribute_variant (t1, attributes);
 }
 
 /* Return the common type of two types.
index c33adfb..e95b301 100644 (file)
@@ -1,3 +1,14 @@
+2004-02-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/13113
+       * g++.old-deja/g++.mike/net36.C: Adjust error messages.
+
+       PR c++/13854
+       * g++.dg/ext/attrib13.C: New test.
+
+       PR c++/13907
+       * g++.dg/conversion/op2.C: New test.
+
 2004-02-02  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * gcc.dg/titype-1.c: Fix pasto.
diff --git a/gcc/testsuite/g++.dg/conversion/op2.C b/gcc/testsuite/g++.dg/conversion/op2.C
new file mode 100644 (file)
index 0000000..b400988
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/13907
+
+struct A {
+  operator int & ();
+  operator const int & () const;
+};
+                                                                               
+          
+void f(int &);
+void f(const int &);
+                                                                               
+          
+int main() {
+  const A x = A();
+  f(x);
+}
diff --git a/gcc/testsuite/g++.dg/ext/attrib13.C b/gcc/testsuite/g++.dg/ext/attrib13.C
new file mode 100644 (file)
index 0000000..22ea97a
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/13854
+
+extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__));
+extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__));
index 3ffa60e..98b38ee 100644 (file)
@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*);
 
 class B {
 public:
-  void setHandler(handler);
+  void setHandler(handler); // { dg-error "candidate" }
 };
 
 void f(B* b) {