name-lookup.c (do_nonmember_using_decl): Print an error for ambiguous type lookups.

gcc/cp/
	* name-lookup.c (do_nonmember_using_decl): Print an error for ambiguous
	type lookups.
	(ambiguous_decl): Construct tree of ambiguous types.  Remove extaneous
	function parameter.
	(unqualified_namespace_lookup): Fix ambiguous_decl call.
	(lookup_using_namespace): Fix ambiguous_decl call.
	(qualified_lookup_using_namespace): Fix ambiguous_decl call.

	gcc/testsuite/
	* g++.dg/lookup/using18.C: New test.

From-SVN: r127347
This commit is contained in:
Ollie Wild 2007-08-10 18:12:12 +00:00 committed by Ollie Wild
parent 68a57691dc
commit 19831e2b8b
4 changed files with 54 additions and 16 deletions

View File

@ -1,3 +1,13 @@
2007-08-10 Ollie Wild <aaw@google.com>
* name-lookup.c (do_nonmember_using_decl): Print an error for ambiguous
type lookups.
(ambiguous_decl): Construct tree of ambiguous types. Remove extaneous
function parameter.
(unqualified_namespace_lookup): Fix ambiguous_decl call.
(lookup_using_namespace): Fix ambiguous_decl call.
(qualified_lookup_using_namespace): Fix ambiguous_decl call.
2007-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* call.c (name_as_c_string): Use CONST_CAST.

View File

@ -2190,12 +2190,20 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
error ("%qD is already declared in this scope", name);
}
*newtype = decls.type;
if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
{
error ("using declaration %qD introduced ambiguous type %qT",
name, oldtype);
return;
error ("reference to %qD is ambiguous", name);
print_candidates (decls.type);
}
else
{
*newtype = decls.type;
if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
{
error ("using declaration %qD introduced ambiguous type %qT",
name, oldtype);
return;
}
}
}
@ -3491,8 +3499,7 @@ merge_functions (tree s1, tree s2)
XXX I don't want to repeat the entire duplicate_decls here */
static void
ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
int flags)
ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
{
tree val, type;
gcc_assert (old != NULL);
@ -3564,12 +3571,9 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
old->type = type;
else if (type && old->type != type)
{
if (flags & LOOKUP_COMPLAIN)
{
error ("%qD denotes an ambiguous type",name);
error ("%J first type here", TYPE_MAIN_DECL (old->type));
error ("%J other type here", TYPE_MAIN_DECL (type));
}
old->type = tree_cons (NULL_TREE, old->type,
build_tree_list (NULL_TREE, type));
TREE_TYPE (old->type) = error_mark_node;
}
}
@ -3680,7 +3684,7 @@ unqualified_namespace_lookup (tree name, int flags)
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
if (b)
ambiguous_decl (name, &binding, b, flags);
ambiguous_decl (&binding, b, flags);
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
@ -3768,7 +3772,7 @@ lookup_using_namespace (tree name, struct scope_binding *val,
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
/* Resolve ambiguities. */
if (val1)
ambiguous_decl (name, val, val1, flags);
ambiguous_decl (val, val1, flags);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
}
@ -3797,7 +3801,7 @@ qualified_lookup_using_namespace (tree name, tree scope,
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
seen = tree_cons (scope, NULL_TREE, seen);
if (binding)
ambiguous_decl (name, result, binding, flags);
ambiguous_decl (result, binding, flags);
/* Consider strong using directives always, and non-strong ones
if we haven't found a binding yet. ??? Shouldn't we consider

View File

@ -1,3 +1,7 @@
2007-08-10 Ollie Wild <aaw@google.com>
* g++.dg/lookup/using18.C: New test.
2007-08-10 Paolo Carlini <pcarlini@suse.de>
PR c++/17763

View File

@ -0,0 +1,20 @@
// Copyright (C) 2007 Free Software Foundation
// Contributed by Ollie Wild <aaw@google.com>
// { dg-do compile }
namespace N1 {
void f ();
struct f; // { dg-error "" "candidate" }
}
namespace N2 {
void f (int);
struct f; // { dg-error "" "candidate" }
}
namespace M {
using namespace N1;
using namespace N2;
}
using M::f; // { dg-error "ambiguous" }