re PR c++/48481 (C++ overloading memory hog)
authorJason Merrill <jason@redhat.com>
Thu, 30 Jun 2011 21:10:03 +0000 (17:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 30 Jun 2011 21:10:03 +0000 (17:10 -0400)
PR c++/48481
* name-lookup.c (struct arg_lookup): Add fn_set.
(add_function): Check it.
(lookup_arg_dependent_1): Initialize it.

From-SVN: r175732

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/template/crash37.C
gcc/testsuite/g++.dg/template/ptrmem4.C
gcc/testsuite/g++.old-deja/g++.other/pmf3.C

index e95e7c8f082128ec4ef22d473aadcab2c265d154..42c21fe2150515b60fdf86e15c6e9d4e4883cc18 100644 (file)
@@ -1,3 +1,10 @@
+2011-06-30  Jason Merrill  <jason@redhat.com>
+
+       PR c++/48481
+       * name-lookup.c (struct arg_lookup): Add fn_set.
+       (add_function): Check it.
+       (lookup_arg_dependent_1): Initialize it.
+
 2011-06-29  Jason Merrill  <jason@redhat.com>
 
        PR c++/49216
index 8bf5f5fde662463525d266667c5f150779360bc7..615e177e1f1b9e0abd467cf09036edc2e6efe4c7 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "debug.h"
 #include "c-family/c-pragma.h"
 #include "params.h"
+#include "pointer-set.h"
 
 /* The bindings for a particular name in a particular scope.  */
 
@@ -4864,6 +4865,7 @@ struct arg_lookup
   VEC(tree,gc) *namespaces;
   VEC(tree,gc) *classes;
   tree functions;
+  struct pointer_set_t *fn_set;
 };
 
 static bool arg_assoc (struct arg_lookup*, tree);
@@ -4883,16 +4885,11 @@ static bool arg_assoc_template_arg (struct arg_lookup*, tree);
 static bool
 add_function (struct arg_lookup *k, tree fn)
 {
-  /* We used to check here to see if the function was already in the list,
-     but that's O(n^2), which is just too expensive for function lookup.
-     Now we deal with the occasional duplicate in joust.  In doing this, we
-     assume that the number of duplicates will be small compared to the
-     total number of functions being compared, which should usually be the
-     case.  */
-
   if (!is_overloaded_fn (fn))
     /* All names except those of (possibly overloaded) functions and
        function templates are ignored.  */;
+  else if (k->fn_set && pointer_set_insert (k->fn_set, fn))
+    /* It's already in the list.  */;
   else if (!k->functions)
     k->functions = fn;
   else if (fn == k->functions)
@@ -5346,6 +5343,23 @@ lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args,
      picking up later definitions) in the second stage. */
   k.namespaces = make_tree_vector ();
 
+  /* We used to allow duplicates and let joust discard them, but
+     since the above change for DR 164 we end up with duplicates of
+     all the functions found by unqualified lookup.  So keep track
+     of which ones we've seen.  */
+  if (fns)
+    {
+      tree ovl;
+      /* We shouldn't be here if lookup found something other than
+        namespace-scope functions.  */
+      gcc_assert (DECL_NAMESPACE_SCOPE_P (OVL_CURRENT (fns)));
+      k.fn_set = pointer_set_create ();
+      for (ovl = fns; ovl; ovl = OVL_NEXT (ovl))
+       pointer_set_insert (k.fn_set, OVL_CURRENT (ovl));
+    }
+  else
+    k.fn_set = NULL;
+
   if (include_std)
     arg_assoc_namespace (&k, std_node);
   arg_assoc_args_vec (&k, args);
@@ -5363,6 +5377,8 @@ lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args,
 
   release_tree_vector (k.classes);
   release_tree_vector (k.namespaces);
+  if (k.fn_set)
+    pointer_set_destroy (k.fn_set);
     
   return fns;
 }
index 60724231eabbbaf324a1faaec3444a515ac32751..d5167c8d2dc26ba878d24f729a3b2ee6353ba753 100644 (file)
@@ -11,7 +11,7 @@ struct coperator_stack
 struct helper {};
 
 template<class F>
-void bla(F f) // { dg-message "bla|no known conversion" }
+void bla(F f)
 {
 }
 
@@ -20,8 +20,7 @@ struct definition
 {
  definition()
  {
-   bla(coperator_stack::push3<helper>); // { dg-error "matching" }
-   // { dg-message "candidate" "candidate note" { target *-*-* } 23 }
+   bla(coperator_stack::push3<helper>); // { dg-error "pointer to member" }
  }
 };
 
index 62262c4b8e9326fcc855a61f2df1ad0f8076d27b..14f36d4e386f5111e7da718224242df913b20b2a 100644 (file)
@@ -16,6 +16,5 @@ struct SpyExample
 
 void SpyExample::ready()
 {
-  queryAliases(inputs); // { dg-error "matching" }
-  // { dg-message "candidate" "candidate note" { target *-*-* } 19 }
+  queryAliases(inputs); // { dg-error "matching|unresolved" }
 }
index 11e648ed86eaaf20d22e201f67cf2e158e1a1870..448d7914571aa38f92b2f53ea200bb4242cfd52b 100644 (file)
@@ -3,7 +3,7 @@
 // Bug: g++ was crashing after giving errors.
 
 template<class T>
-  void connect_to_method( // { dg-message "connect_to_method|no known conversion" }
+  void connect_to_method(
     T *receiver,
     void (T::*method)())
   {}
@@ -20,7 +20,6 @@ public:
 
 Gtk_Base::Gtk_Base()
 {
-  connect_to_method(this,&show);   // { dg-error "no match" } invalid pmf expression
-  // { dg-message "candidate" "candidate note" { target *-*-* } 23 }
+  connect_to_method(this,&show);   // { dg-error "pointer to member" } invalid pmf expression
   connect_to_method(this,&expose); // { dg-error "pointer to member" } invalid pmf expression
 }