aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-08-17 17:32:37 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-08-17 17:32:37 +0000
commit8f78f01f72f21078e0169abe6c214e62a1414c93 (patch)
tree697ec760d74298d58c6bb50a122c01bbfe86c05b /gcc
parent13a98f14d2c358714567c8284f7eefa419f2b076 (diff)
downloadgcc-8f78f01f72f21078e0169abe6c214e62a1414c93.zip
gcc-8f78f01f72f21078e0169abe6c214e62a1414c93.tar.gz
gcc-8f78f01f72f21078e0169abe6c214e62a1414c93.tar.bz2
re PR c++/16965 (Confusing mismatch in error messages)
PR c++/16965 * cp-tree.h (qualified_name_lookup_error): Add parameter. * name-lookup.c (do_class_using_decl): Restrict set of entities passed to cp_emit_debug_info_for_using more carefully. (lookup_qualified_name): Allow lookup_member to return sets of ambiguous entries. * parser.c (cp_parser_lookup_name): Add ambiguous_p parameter. (cp_parser_primary_expression): Handle ambiguous lookups. (cp_parser_template_name): Adjust use of cp_parser_lookup_name. (cp_parser_template_argument): Likewise. (cp_parser_elaborate_type_specifier): Likewise. (cp_parser_namespace_name): Likewise. (cp_parser_class_name): Likewise. (cp_parser_lookup_name_simple): Likewise. * pt.c (tsubst_qualified_id): Handle ambiguous results. (tsubst_expr): Likewise. * semantics.c (qualified_name_lookup_error): Add decl paramter. For ambiguous lookups, print candidates. PR c++/16965 * g++.dg/parse/error17.C: New test. From-SVN: r86137
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog21
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c6
-rw-r--r--gcc/cp/parser.c50
-rw-r--r--gcc/cp/pt.c31
-rw-r--r--gcc/cp/semantics.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/error17.C8
8 files changed, 107 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2946db7..7ccf881 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,24 @@
+2004-08-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16965
+ * cp-tree.h (qualified_name_lookup_error): Add parameter.
+ * name-lookup.c (do_class_using_decl): Restrict set of entities
+ passed to cp_emit_debug_info_for_using more carefully.
+ (lookup_qualified_name): Allow lookup_member to return sets of
+ ambiguous entries.
+ * parser.c (cp_parser_lookup_name): Add ambiguous_p parameter.
+ (cp_parser_primary_expression): Handle ambiguous lookups.
+ (cp_parser_template_name): Adjust use of cp_parser_lookup_name.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_elaborate_type_specifier): Likewise.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name_simple): Likewise.
+ * pt.c (tsubst_qualified_id): Handle ambiguous results.
+ (tsubst_expr): Likewise.
+ * semantics.c (qualified_name_lookup_error): Add decl paramter.
+ For ambiguous lookups, print candidates.
+
2004-08-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6749
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 72011f7..04a39b7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4166,7 +4166,7 @@ extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree);
extern void check_multiple_declarators (void);
-extern void qualified_name_lookup_error (tree, tree);
+extern void qualified_name_lookup_error (tree, tree, tree);
extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *, tree *,
bool, bool, bool *,
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 2859d80..ccef113 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2953,7 +2953,7 @@ do_class_using_decl (tree decl)
tree r;
r = lookup_qualified_name (scope, name, false, false);
- if (r && TREE_CODE (r) != ERROR_MARK)
+ if (r && (DECL_P (r) || TREE_CODE (r) == OVERLOAD))
cp_emit_debug_info_for_using (r, scope);
}
return value;
@@ -3813,7 +3813,7 @@ unqualified_namespace_lookup (tree name, int flags)
Returns a DECL (or OVERLOAD, or BASELINK) representing the
declaration found. If no suitable declaration can be found,
- ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is
+ ERROR_MARK_NODE is returned. If COMPLAIN is true and SCOPE is
neither a class-type nor a namespace a diagnostic is issued. */
tree
@@ -3834,7 +3834,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
else if (is_aggr_type (scope, complain))
{
tree t;
- t = lookup_member (scope, name, 0, is_type_p);
+ t = lookup_member (scope, name, 2, is_type_p);
if (t)
return t;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2193bac..fa41ce6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1831,7 +1831,7 @@ static void cp_parser_label_declaration
/* Utility Routines */
static tree cp_parser_lookup_name
- (cp_parser *, tree, bool, bool, bool, bool);
+ (cp_parser *, tree, bool, bool, bool, bool, bool *);
static tree cp_parser_lookup_name_simple
(cp_parser *, tree);
static tree cp_parser_maybe_treat_template_as_class
@@ -2905,7 +2905,18 @@ cp_parser_primary_expression (cp_parser *parser,
/* Look up the name. */
else
{
- decl = cp_parser_lookup_name_simple (parser, id_expression);
+ bool ambiguous_p;
+
+ decl = cp_parser_lookup_name (parser, id_expression,
+ /*is_type=*/false,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true,
+ &ambiguous_p);
+ /* If the lookup was ambiguous, an error will already have
+ been issued. */
+ if (ambiguous_p)
+ return error_mark_node;
/* If name lookup gives us a SCOPE_REF, then the
qualifying scope was dependent. Just propagate the
name. */
@@ -8331,7 +8342,8 @@ cp_parser_type_parameter (cp_parser* parser)
/*is_type=*/false,
/*is_template=*/is_template,
/*is_namespace=*/false,
- /*check_dependency=*/true);
+ /*check_dependency=*/true,
+ /*ambiguous_p=*/NULL);
/* See if the default argument is valid. */
default_argument
= check_template_template_default_arg (default_argument);
@@ -8710,7 +8722,8 @@ cp_parser_template_name (cp_parser* parser,
/*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/false,
- check_dependency_p);
+ check_dependency_p,
+ /*ambiguous_p=*/NULL);
decl = maybe_get_template_decl_from_type_decl (decl);
/* If DECL is a template, then the name was a template-name. */
@@ -8900,7 +8913,8 @@ cp_parser_template_argument (cp_parser* parser)
/*is_type=*/false,
/*is_template=*/template_p,
/*is_namespace=*/false,
- /*check_dependency=*/true);
+ /*check_dependency=*/true,
+ /*ambiguous_p=*/NULL);
if (TREE_CODE (argument) != TEMPLATE_DECL
&& TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
cp_parser_error (parser, "expected template-name");
@@ -9753,7 +9767,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/*is_type=*/true,
/*is_template=*/false,
/*is_namespace=*/false,
- /*check_dependency=*/true);
+ /*check_dependency=*/true,
+ /*ambiguous_p=*/NULL);
/* If we are parsing friend declaration, DECL may be a
TEMPLATE_DECL tree node here. However, we need to check
@@ -10029,7 +10044,8 @@ cp_parser_namespace_name (cp_parser* parser)
/*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/true,
- /*check_dependency=*/true);
+ /*check_dependency=*/true,
+ /*ambiguous_p=*/NULL);
/* If it's not a namespace, issue an error. */
if (namespace_decl == error_mark_node
|| TREE_CODE (namespace_decl) != NAMESPACE_DECL)
@@ -12239,7 +12255,8 @@ cp_parser_class_name (cp_parser *parser,
type_p,
/*is_template=*/false,
/*is_namespace=*/false,
- check_dependency_p);
+ check_dependency_p,
+ /*ambiguous_p=*/NULL);
}
}
else
@@ -14121,16 +14138,24 @@ cp_parser_label_declaration (cp_parser* parser)
are ignored.
If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
- types. */
+ types.
+
+ If AMBIGUOUS_P is non-NULL, it is set to true if name-lookup
+ results in an ambiguity, and false otherwise. */
static tree
cp_parser_lookup_name (cp_parser *parser, tree name,
bool is_type, bool is_template, bool is_namespace,
- bool check_dependency)
+ bool check_dependency,
+ bool *ambiguous_p)
{
tree decl;
tree object_type = parser->context->object_type;
+ /* Assume that the lookup will be unambiguous. */
+ if (ambiguous_p)
+ *ambiguous_p = false;
+
/* Now that we have looked up the name, the OBJECT_TYPE (if any) is
no longer valid. Note that if we are parsing tentatively, and
the parse fails, OBJECT_TYPE will be automatically restored. */
@@ -14278,6 +14303,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
/* If it's a TREE_LIST, the result of the lookup was ambiguous. */
if (TREE_CODE (decl) == TREE_LIST)
{
+ if (ambiguous_p)
+ *ambiguous_p = true;
/* The error message we have to print is too complicated for
cp_parser_error, so we incorporate its actions directly. */
if (!cp_parser_simulate_error (parser))
@@ -14319,7 +14346,8 @@ cp_parser_lookup_name_simple (cp_parser* parser, tree name)
/*is_type=*/false,
/*is_template=*/false,
/*is_namespace=*/false,
- /*check_dependency=*/true);
+ /*check_dependency=*/true,
+ /*ambiguous_p=*/NULL);
}
/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d3d5267..74322df 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7396,18 +7396,28 @@ tsubst_qualified_id (tree qualified_id, tree args,
}
if (DECL_P (expr))
- check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
- scope);
-
- /* Remember that there was a reference to this entity. */
- if (DECL_P (expr))
- mark_used (expr);
+ {
+ check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+ scope);
+ /* Remember that there was a reference to this entity. */
+ mark_used (expr);
+ }
+
+ if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST)
+ {
+ if (complain & tf_error)
+ qualified_name_lookup_error (scope,
+ TREE_OPERAND (qualified_id, 1),
+ expr);
+ return error_mark_node;
+ }
if (is_template)
expr = lookup_template_function (expr, template_args);
if (expr == error_mark_node && complain & tf_error)
- qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
+ qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
+ expr);
else if (TYPE_P (scope))
{
expr = (adjust_result_of_qualified_name_lookup
@@ -7855,8 +7865,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
decl = lookup_qualified_name (scope, name,
/*is_type_p=*/false,
/*complain=*/false);
- if (decl == error_mark_node)
- qualified_name_lookup_error (scope, name);
+ if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+ qualified_name_lookup_error (scope, name, decl);
else
do_local_using_decl (decl, scope, name);
}
@@ -8510,7 +8520,8 @@ tsubst_copy_and_build (tree t,
args);
else
{
- qualified_name_lookup_error (TREE_TYPE (object), tmpl);
+ qualified_name_lookup_error (TREE_TYPE (object), tmpl,
+ member);
return error_mark_node;
}
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 393020f..f21c926 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2290,15 +2290,21 @@ check_multiple_declarators (void)
error ("multiple declarators in template declaration");
}
-/* Issue a diagnostic that NAME cannot be found in SCOPE. */
+/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
+ what we found when we tried to do the lookup. */
void
-qualified_name_lookup_error (tree scope, tree name)
+qualified_name_lookup_error (tree scope, tree name, tree decl)
{
if (TYPE_P (scope))
{
if (!COMPLETE_TYPE_P (scope))
error ("incomplete type `%T' used in nested name specifier", scope);
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ error ("reference to `%T::%D' is ambiguous", scope, name);
+ print_candidates (decl);
+ }
else
error ("`%D' is not a member of `%T'", name, scope);
}
@@ -2374,7 +2380,7 @@ finish_id_expression (tree id_expression,
/* If the qualifying type is non-dependent (and the name
does not name a conversion operator to a dependent
type), issue an error. */
- qualified_name_lookup_error (scope, id_expression);
+ qualified_name_lookup_error (scope, id_expression, decl);
return error_mark_node;
}
else if (!scope)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6434481..cd593dd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-08-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/16965
+ * g++.dg/parse/error17.C: New test.
+
2004-08-17 Dorit Naishlos <dorit@il.ibm.com>
* gcc.dg/vect: New directory for vectorizer tests.
diff --git a/gcc/testsuite/g++.dg/parse/error17.C b/gcc/testsuite/g++.dg/parse/error17.C
new file mode 100644
index 0000000..2a8f3f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error17.C
@@ -0,0 +1,8 @@
+// PR c++/16965
+
+template <typename T> struct B {
+ static int Bar(T); // { dg-error "" }
+};
+struct D : B<int>, B<char> {};
+
+int i2 = D::Bar(2); // { dg-error "" }