summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-05 06:24:47 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-05 06:24:47 +0000
commitf3ccd0ea4e122b3914b08b1606cef2a47c5208ff (patch)
tree8839f7280c9dbcd84c08e24327572e09044a43e1
parent2a0d3beb8e009e1a816947ace9571782f08486f9 (diff)
downloadgcc-f3ccd0ea4e122b3914b08b1606cef2a47c5208ff.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75416 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/name-lookup.c41
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/koenig3.C28
4 files changed, 64 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ad9804e3aeb..e3baeebd3df 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0be758f450d..a7888161d1a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 258604725b1..9b161c459b9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..f90059d653b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/koenig3.C
@@ -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);
+}
+