]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c++/9053 (g++ confused about ambiguity of overloaded function templates)
authorNathan Sidwell <nathan@gcc.gnu.org>
Tue, 24 Dec 2002 22:12:17 +0000 (22:12 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 24 Dec 2002 22:12:17 +0000 (22:12 +0000)
cp:
        PR c++/9053
        * decl.c (duplicate_decls): Templates may be disambiguated by
        return type.

        PR c++/8702
        * decl2.c (check_classfn): Use lookup_fnfield_1. List all
        conversion operators on failure.
testsuite
        * g++.dg/lookup/decl1.C: New test.
        * g++.dg/lookup/decl2.C: New test.

From-SVN: r60482

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/decl1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/decl2.C [new file with mode: 0644]

index 5776e5c470e390dc3fa0fc7e364c0946f42c13bf..921550ed4b2f9cec3f3e0364be9389c77554ceaa 100644 (file)
@@ -1,3 +1,13 @@
+2002-12-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/9053
+       * decl.c (duplicate_decls): Templates may be disambiguated by
+       return type.
+       
+       PR c++/8702
+       * decl2.c (check_classfn): Use lookup_fnfield_1. List all
+       conversion operators on failure.
+
 2002-12-23  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * call.c (tourney, build_field_call, equal_functions, joust) 
index eef5335fb5fefe4d426b6a48ab52724c7d50e318..95680dd60fa10b919655d215d6c44cb2c15ee389 100644 (file)
@@ -3212,7 +3212,11 @@ duplicate_decls (newdecl, olddecl)
                   && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
                                 TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
                   && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
-                                          DECL_TEMPLATE_PARMS (olddecl)))
+                                          DECL_TEMPLATE_PARMS (olddecl))
+                  /* Template functions can be disambiguated by
+                     return type.  */
+                  && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
+                                  TREE_TYPE (TREE_TYPE (olddecl))))
            {
              error ("new declaration `%#D'", newdecl);
              cp_error_at ("ambiguates old declaration `%#D'", olddecl);
index d305ee5813e52ab2c0cb267df238d1ff55ba3e16..afb8693a6b730643285377b96e6318ca008cd848 100644 (file)
@@ -676,11 +676,7 @@ tree
 check_classfn (ctype, function)
      tree ctype, function;
 {
-  tree fn_name = DECL_NAME (function);
-  tree fndecl, fndecls;
-  tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
-  tree *methods = 0;
-  tree *end = 0;
+  int ix;
   
   if (DECL_USE_TEMPLATE (function)
       && !(TREE_CODE (function) == TEMPLATE_DECL
@@ -697,81 +693,90 @@ check_classfn (ctype, function)
        reason we should, either.  We let our callers know we didn't
        find the method, but we don't complain.  */
     return NULL_TREE;
-      
-  if (method_vec != 0)
+
+  ix = lookup_fnfields_1 (complete_type (ctype),
+                         DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
+                         DECL_DESTRUCTOR_P (function) ? dtor_identifier :
+                         DECL_NAME (function));
+
+  if (ix >= 0)
     {
-      methods = &TREE_VEC_ELT (method_vec, 0);
-      end = TREE_VEC_END (method_vec);
-
-      /* First suss out ctors and dtors.  */
-      if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
-         && DECL_CONSTRUCTOR_P (function))
-       goto got_it;
-      if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
-         && DECL_DESTRUCTOR_P (function))
-       goto got_it;
-
-      while (++methods != end && *methods)
+      tree methods = CLASSTYPE_METHOD_VEC (ctype);
+      tree fndecls, fndecl;
+      bool is_conv_op;
+      const char *format = NULL;
+      
+      for (fndecls = TREE_VEC_ELT (methods, ix);
+          fndecls; fndecls = OVL_NEXT (fndecls))
+       {
+         tree p1, p2;
+         
+         fndecl = OVL_CURRENT (fndecls);
+         p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
+         p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+
+         /* We cannot simply call decls_match because this doesn't
+            work for static member functions that are pretending to
+            be methods, and because the name may have been changed by
+            asm("new_name").  */ 
+             
+          /* Get rid of the this parameter on functions that become
+             static.  */
+         if (DECL_STATIC_FUNCTION_P (fndecl)
+             && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
+           p1 = TREE_CHAIN (p1);
+             
+         if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
+                          TREE_TYPE (TREE_TYPE (fndecl)))
+             && compparms (p1, p2)
+             && (DECL_TEMPLATE_SPECIALIZATION (function)
+                 == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+             && (!DECL_TEMPLATE_SPECIALIZATION (function)
+                 || (DECL_TI_TEMPLATE (function) 
+                     == DECL_TI_TEMPLATE (fndecl))))
+           return fndecl;
+       }
+      error ("prototype for `%#D' does not match any in class `%T'",
+            function, ctype);
+      is_conv_op = DECL_CONV_FN_P (fndecl);
+
+      if (is_conv_op)
+       ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
+      fndecls = TREE_VEC_ELT (methods, ix);
+      while (fndecls)
        {
-         fndecl = *methods;
-         if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))
+         fndecl = OVL_CURRENT (fndecls);
+         fndecls = OVL_NEXT (fndecls);
+
+         if (!fndecls && is_conv_op)
            {
-           got_it:
-             for (fndecls = *methods; fndecls != NULL_TREE;
-                  fndecls = OVL_NEXT (fndecls))
+             if (TREE_VEC_LENGTH (methods) > ix)
                {
-                 fndecl = OVL_CURRENT (fndecls);
-
-                 /* We cannot simply call decls_match because this
-                    doesn't work for static member functions that are 
-                     pretending to be methods, and because the name
-                    may have been changed by asm("new_name").  */ 
-                 if (DECL_NAME (function) == DECL_NAME (fndecl))
+                 ix++;
+                 fndecls = TREE_VEC_ELT (methods, ix);
+                 if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
                    {
-                     tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
-                     tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
-
-                     /* Get rid of the this parameter on functions that become
-                        static.  */
-                     if (DECL_STATIC_FUNCTION_P (fndecl)
-                         && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
-                       p1 = TREE_CHAIN (p1);
-
-                     if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
-                                      TREE_TYPE (TREE_TYPE (fndecl)))
-                         && compparms (p1, p2)
-                         && (DECL_TEMPLATE_SPECIALIZATION (function)
-                             == DECL_TEMPLATE_SPECIALIZATION (fndecl))
-                         && (!DECL_TEMPLATE_SPECIALIZATION (function)
-                             || (DECL_TI_TEMPLATE (function) 
-                                 == DECL_TI_TEMPLATE (fndecl))))
-                       return fndecl;
+                     fndecls = NULL_TREE;
+                     is_conv_op = false;
                    }
                }
-             break;            /* loser */
+             else
+               is_conv_op = false;
            }
+         if (format)
+           format = "                %#D";
+         else if (fndecls)
+           format = "candidates are: %#D";
+         else
+           format = "candidate is: %#D";
+         cp_error_at (format, fndecl);
        }
     }
-
-  if (methods != end && *methods)
-    {
-      tree fndecl = *methods;
-      error ("prototype for `%#D' does not match any in class `%T'",
-               function, ctype);
-      cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",
-                  OVL_CURRENT (fndecl));
-      while (fndecl = OVL_NEXT (fndecl), fndecl)
-       cp_error_at ("                %#D", OVL_CURRENT(fndecl));
-    }
+  else if (!COMPLETE_TYPE_P (ctype))
+    cxx_incomplete_type_error (function, ctype);
   else
-    {
-      methods = 0;
-      if (!COMPLETE_TYPE_P (ctype))
-        cxx_incomplete_type_error (function, ctype);
-      else
-        error ("no `%#D' member function declared in class `%T'",
-                 function, ctype);
-    }
+    error ("no `%#D' member function declared in class `%T'",
+          function, ctype);
 
   /* If we did not find the method in the class, add it to avoid
      spurious errors (unless the CTYPE is not yet defined, in which
index 7771c26a1d51c0c7d3895929110032d729ce998b..b40420e24c3d490229a6f7d56c903872ba78d254 100644 (file)
@@ -1,3 +1,8 @@
+2002-12-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/lookup/decl1.C: New test.
+       * g++.dg/lookup/decl2.C: New test.
+
 2002-12-24  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * g++.dg/init/new1.C, g++.dg/template/alignof1.C,
@@ -12,9 +17,9 @@
 
 2002-12-23  Mark Mitchell  <mark@codesourcery.com>
 
-       * testsuite/gcc.dg/i386-bitfield3.c: New test.
+       * gcc.dg/i386-bitfield3.c: New test.
        
-       * testsuite/gcc.dg/i386-bitfield2.c: New test.
+       * gcc.dg/i386-bitfield2.c: New test.
        
 2002-12-22  Nathan Sidwell  <nathan@codesourcery.com>
 
diff --git a/gcc/testsuite/g++.dg/lookup/decl1.C b/gcc/testsuite/g++.dg/lookup/decl1.C
new file mode 100644 (file)
index 0000000..d9af656
--- /dev/null
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>
+
+// PR 8702. Failure to match templates.
+
+template <typename X> struct C1{};
+
+template <typename X>
+struct C2 {
+  template<typename Y> operator C1<Y>();
+  template<typename Y> operator C2<Y>();
+};
+
+template<typename X> template<typename Y>
+C2<X>::operator C1<Y>()
+{
+  return C1<Y>();
+}
+
+struct A
+{
+  operator int ();                     // { dg-error "operator" "" }
+  operator float ();                   // { dg-error "operator" "" }
+  operator float () const;             // { dg-error "operator" "" }
+  template <typename T> operator T * (); // { dg-error "candidates" "" }
+};
+
+A::operator short () { // { dg-error "prototype for" "" }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lookup/decl2.C b/gcc/testsuite/g++.dg/lookup/decl2.C
new file mode 100644 (file)
index 0000000..75ce096
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>
+// Source Martin Buchholz martin@xemacs.org
+
+// PR 9053. Failed to consider templates that are disambiguated by
+// return type.
+
+template <typename T> class bar;
+template <> struct bar<const char*> { typedef void type; };
+template <typename T> class qux;
+template <> struct qux<int> { typedef void type; };
+
+template <typename T>
+typename bar<T>::type foo (T t) { }
+
+template <typename T>
+typename qux<T>::type foo (T t) { }
+
+
+int
+main (int argc, char *argv[])
+{
+  foo ("foo");
+  foo (7);
+}
This page took 0.095564 seconds and 5 git commands to generate.