* PATCH: detect ambiguous types in using declarations
@ 2007-08-07 6:15 Ollie Wild
2007-08-10 16:47 ` Mark Mitchell
0 siblings, 1 reply; 2+ messages in thread
From: Ollie Wild @ 2007-08-07 6:15 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 859 bytes --]
If the qualified-id in a using declaration nominates ambiguous hidden
class or enumerator names, the current code generates an unhelpful
error message followed by an ICE. This patch generates a more
detailed error message and handles the event gracefully.
Tested with a C/C++/Java bootstrap and testsuite on i686-pc-linux-gnu.
Ollie
:ADDPATCH c++:
2007-08-06 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-06 Ollie Wild <aaw@google.com>
* g++.dg/lookup/using18.C: New test.
[-- Attachment #2: ambiguous_types.patch --]
[-- Type: text/x-patch, Size: 3544 bytes --]
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 81145b0..48b387a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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
diff --git a/gcc/testsuite/g++.dg/lookup/using18.C b/gcc/testsuite/g++.dg/lookup/using18.C
new file mode 100644
index 0000000..3755714
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/using18.C
@@ -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" }
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: PATCH: detect ambiguous types in using declarations
2007-08-07 6:15 PATCH: detect ambiguous types in using declarations Ollie Wild
@ 2007-08-10 16:47 ` Mark Mitchell
0 siblings, 0 replies; 2+ messages in thread
From: Mark Mitchell @ 2007-08-10 16:47 UTC (permalink / raw)
To: Ollie Wild; +Cc: GCC Patches
Ollie Wild wrote:
> :ADDPATCH c++:
>
> 2007-08-06 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-06 Ollie Wild <aaw@google.com>
>
> * g++.dg/lookup/using18.C: New test.
:REVIEWMAIL: OK
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-08-10 16:47 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-07 6:15 PATCH: detect ambiguous types in using declarations Ollie Wild
2007-08-10 16:47 ` Mark Mitchell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).