From 8f78f01f72f21078e0169abe6c214e62a1414c93 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 17 Aug 2004 17:32:37 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 21 ++++++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/name-lookup.c | 6 ++-- gcc/cp/parser.c | 50 ++++++++++++++++++++++------ gcc/cp/pt.c | 31 +++++++++++------ gcc/cp/semantics.c | 12 +++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/parse/error17.C | 8 +++++ 8 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/error17.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2946db75671..7ccf881bd54 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2004-08-17 Mark Mitchell + + 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 PR c++/6749 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 72011f7356f..04a39b7d08b 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 2859d8035b9..ccef113b5bc 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 2193bacc3e6..fa41ce6b00d 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 d3d5267dcef..74322df0663 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 393020f3970..f21c926d1dd 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 64344815c7d..cd593ddcc72 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-08-17 Mark Mitchell + + PR c++/16965 + * g++.dg/parse/error17.C: New test. + 2004-08-17 Dorit Naishlos * 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 00000000000..2a8f3f829ca --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error17.C @@ -0,0 +1,8 @@ +// PR c++/16965 + +template struct B { + static int Bar(T); // { dg-error "" } +}; +struct D : B, B {}; + +int i2 = D::Bar(2); // { dg-error "" } -- 2.30.2