re PR c++/13157 (Argument Dependent Lookup Failure)
authorMark Mitchell <mark@codesourcery.com>
Mon, 5 Jan 2004 06:24:47 +0000 (06:24 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 5 Jan 2004 06:24:47 +0000 (06:24 +0000)
PR c++/13157
* name-lookup.c (lookup_using_namespace): Remove spacesp
parameter.
(unqualified_namespace_lookup): Likewise.
(lookup_qualified_name): Adjust accordingly.
(lookup_name_real): Likewise.
(lookup_arg_dependent): Do not eliminate the namespace of the
functions found by unqualified name lookup unless that is the
current namespace.

PR c++/13157
* g++.dg/template/koenig3.C: New test.

From-SVN: r75416

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/koenig3.C [new file with mode: 0644]

index ad9804e..e3baeeb 100644 (file)
@@ -1,3 +1,15 @@
+2004-01-04  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/13157
+       * name-lookup.c (lookup_using_namespace): Remove spacesp
+       parameter.
+       (unqualified_namespace_lookup): Likewise.
+       (lookup_qualified_name): Adjust accordingly.
+       (lookup_name_real): Likewise.
+       (lookup_arg_dependent): Do not eliminate the namespace of the
+       functions found by unqualified name lookup unless that is the
+       current namespace.
+
 2004-01-04  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * semantics.c (push_deferring_access_checks): Fix format.
index 0be758f..a788816 100644 (file)
@@ -38,7 +38,7 @@ static tree lookup_name_current_level (tree);
 static void push_local_binding (tree, tree, int);
 static tree push_overloaded_decl (tree, int);
 static bool lookup_using_namespace (tree, cxx_binding *, tree,
-                                    tree, int, tree *);
+                                    tree, int);
 static bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
 static tree lookup_type_current_level (tree);
 static tree push_using_directive (tree);
@@ -3640,11 +3640,10 @@ select_decl (cxx_binding *binding, int flags)
 }
 
 /* Unscoped lookup of a global: iterate over current namespaces,
-   considering using-directives.  If SPACESP is non-NULL, store a list
-   of the namespaces we've considered in it.  */
+   considering using-directives.  */
 
 static tree
-unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
+unqualified_namespace_lookup (tree name, int flags)
 {
   tree initial = current_decl_namespace ();
   tree scope = initial;
@@ -3655,15 +3654,11 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
 
   timevar_push (TV_NAME_LOOKUP);
   cxx_binding_clear (&binding);
-  if (spacesp)
-    *spacesp = NULL_TREE;
 
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
       cxx_binding *b =
          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
-      if (spacesp)
-       *spacesp = tree_cons (scope, NULL_TREE, *spacesp);
 
       /* Ignore anticipated built-in functions.  */
       if (b && b->value && DECL_P (b->value)
@@ -3681,7 +3676,7 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
           level->kind != sk_namespace;
           level = level->level_chain)
        if (!lookup_using_namespace (name, &binding, level->using_directives,
-                                     scope, flags, spacesp))
+                                     scope, flags))
          /* Give up because of error.  */
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
@@ -3692,7 +3687,7 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
        {
          if (!lookup_using_namespace (name, &binding,
                                        DECL_NAMESPACE_USING (siter),
-                                      scope, flags, spacesp))
+                                      scope, flags))
            /* Give up because of error.  */
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
          if (siter == scope) break;
@@ -3728,8 +3723,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
       flags |= LOOKUP_COMPLAIN;
       if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
-      if (qualified_lookup_using_namespace (name, scope, &binding, 
-                                           flags))
+      if (qualified_lookup_using_namespace (name, scope, &binding, flags))
        return select_decl (&binding, flags);
     }
   else if (is_aggr_type (scope, complain))
@@ -3752,7 +3746,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
 
 static bool
 lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
-                        int flags, tree *spacesp)
+                        int flags)
 {
   tree iter;
   timevar_push (TV_NAME_LOOKUP);
@@ -3764,8 +3758,6 @@ lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
         tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
         cxx_binding *val1 =
           cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
-        if (spacesp)
-          *spacesp = tree_cons (used, NULL_TREE, *spacesp);
         /* Resolve ambiguities.  */
         if (val1)
           val = ambiguous_decl (name, val, val1, flags);
@@ -3900,7 +3892,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass,
   /* Now lookup in namespace scopes.  */
   if (!val)
     {
-      tree t = unqualified_namespace_lookup (name, flags, 0);
+      tree t = unqualified_namespace_lookup (name, flags);
       if (t)
        val = t;
     }
@@ -4371,14 +4363,23 @@ lookup_arg_dependent (tree name, tree fns, tree args)
   k.functions = fns;
   k.classes = NULL_TREE;
 
-  /* Note that we've already looked at some namespaces during normal
-     unqualified lookup, unless we found a decl in function scope.  */
+  /* We've already looked at some namespaces during normal unqualified
+     lookup -- but we don't know exactly which ones.  If the functions
+     we found were brought into the current namespace via a using
+     declaration, we have not really checked the namespace from which
+     they came.  Therefore, we check all namespaces here -- unless the
+     function we have is from the current namespace.  */
   if (fns)
     fn = OVL_CURRENT (fns);
-  if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (fn))
+  if (fn && TREE_CODE (fn) == FUNCTION_DECL 
+      && CP_DECL_CONTEXT (fn) != current_decl_namespace ())
     k.namespaces = NULL_TREE;
   else
-    unqualified_namespace_lookup (name, 0, &k.namespaces);
+    /* Setting NAMESPACES is purely an optimization; it prevents
+       adding functions which are already in FNS.  Adding them would
+       be safe -- "joust" will eliminate the duplicates -- but
+       wasteful.  */
+    k.namespaces = build_tree_list (current_decl_namespace (), NULL_TREE);
 
   arg_assoc_args (&k, args);
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
index 2586047..9b161c4 100644 (file)
@@ -1,5 +1,8 @@
 2004-01-04  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/13157
+       * g++.dg/template/koenig3.C: New test.
+
        PR c++/13529
        * g++.dg/parse/offsetof3.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/template/koenig3.C b/gcc/testsuite/g++.dg/template/koenig3.C
new file mode 100644 (file)
index 0000000..f90059d
--- /dev/null
@@ -0,0 +1,28 @@
+// PR c++/13157
+
+namespace aa
+{
+  double abs(double);
+  long double abs(long double);
+}
+
+namespace fu
+{
+  template <class T>
+  struct X
+  {};
+  
+  template <class T>
+  X<T> test(X<T> x)
+  {
+    using ::aa::abs;
+    return abs(x);
+  }
+  
+  template <class T>
+  X<T> abs(X<T>);
+  
+  X<int> x;
+  X<int> z = test(x);
+}
+