From 22038b2cf5871bdb8613ef35358bc87e478696cf Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 25 Jul 2003 16:35:20 +0000 Subject: [PATCH] re PR c++/11617 (g++ does not report missing member functions) cp: PR c++/11617 * cp-tree.h (qualified_name_lookup_error): Declare. * pt.c (tsubst_qualified_id): Use qualified_name_lookup_error for errors. (tsubst_expr) : Likewise. (tsubst_copy_and_build) : Likewise. * semantics.c (qualified_name_lookup_error): New, broken out of ... (finish_id_expression): ... here. Use it. testsuite: PR c++/11617 * g++.dg/template/lookup2.C: New test. * g++.dg/template/memclass1.C: Remove instantiated from error. From-SVN: r69790 --- gcc/cp/ChangeLog | 11 ++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/pt.c | 27 ++++++++++--------- gcc/cp/semantics.c | 32 +++++++++++++++-------- gcc/testsuite/ChangeLog | 6 ++++- gcc/testsuite/g++.dg/template/lookup2.C | 18 +++++++++++++ gcc/testsuite/g++.dg/template/memclass1.C | 2 +- 7 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/lookup2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 703df4babd2..0ae6496ba8a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2003-07-25 Nathan Sidwell + + PR c++/11617 + * cp-tree.h (qualified_name_lookup_error): Declare. + * pt.c (tsubst_qualified_id): Use qualified_name_lookup_error for + errors. + (tsubst_expr) : Likewise. + (tsubst_copy_and_build) : Likewise. + * semantics.c (qualified_name_lookup_error): New, broken out of ... + (finish_id_expression): ... here. Use it. + 2003-07-25 Falk Hueffner * cfns.gperf: Add '%%' delimiter to placate gperf 3.0. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8f543b4317e..994298a061c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4159,6 +4159,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 tree finish_id_expression (tree, tree, tree, cp_id_kind *, tree *, bool, bool, bool *, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f91dca03c47..24c07bbdb24 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7150,8 +7150,7 @@ tsubst_qualified_id (tree qualified_id, tree args, } if (!BASELINK_P (name) && !DECL_P (expr)) - expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, - (complain & tf_error) != 0); + expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false); if (DECL_P (expr)) check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, @@ -7168,7 +7167,9 @@ tsubst_qualified_id (tree qualified_id, tree args, if (is_template) expr = lookup_template_function (expr, template_args); - if (TYPE_P (scope)) + if (expr == error_mark_node && complain & tf_error) + qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1)); + else if (TYPE_P (scope)) { expr = (adjust_result_of_qualified_name_lookup (expr, scope, current_class_type)); @@ -7589,12 +7590,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree scope = DECL_INITIAL (decl); tree name = DECL_NAME (decl); + tree decl; scope = tsubst_expr (scope, args, complain, in_decl); - do_local_using_decl (lookup_qualified_name (scope, - name, - /*is_type_p=*/0, - /*complain=*/true)); + decl = lookup_qualified_name (scope, name, + /*is_type_p=*/0, /*complain=*/false); + if (decl == error_mark_node) + qualified_name_lookup_error (scope, name); + else + do_local_using_decl (decl); } else { @@ -8252,18 +8256,15 @@ tsubst_copy_and_build (tree t, scope is. */ tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0); args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); - member = lookup_qualified_name (TREE_OPERAND (member, 0), - tmpl, - /*is_type=*/0, - /*complain=*/true); + member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, + /*is_type=*/0, /*complain=*/false); if (BASELINK_P (member)) BASELINK_FUNCTIONS (member) = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), args); else { - error ("`%D' is not a member of `%T'", - tmpl, TREE_TYPE (object)); + qualified_name_lookup_error (TREE_TYPE (object), tmpl); return error_mark_node; } } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 102653a338e..50c74780daf 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2248,6 +2248,24 @@ check_multiple_declarators (void) error ("multiple declarators in template declaration"); } +/* Issue a diagnostic that NAME cannot be found in SCOPE. */ + +void +qualified_name_lookup_error (tree scope, tree name) +{ + if (TYPE_P (scope)) + { + if (!COMPLETE_TYPE_P (scope)) + error ("incomplete type `%T' used in nested name specifier", scope); + else + error ("`%D' is not a member of `%T'", name, scope); + } + else if (scope != global_namespace) + error ("`%D' is not a member of `%D'", name, scope); + else + error ("`::%D' has not been declared", name); +} + /* ID_EXPRESSION is a representation of parsed, but unprocessed, id-expression. (See cp_parser_id_expression for details.) SCOPE, if non-NULL, is the type or namespace used to explicitly qualify @@ -2307,17 +2325,9 @@ finish_id_expression (tree id_expression, if (scope && (!TYPE_P (scope) || !dependent_type_p (scope))) { /* Qualified name lookup failed, and the qualifying name - was not a dependent type. That is always an - error. */ - if (TYPE_P (scope) && !COMPLETE_TYPE_P (scope)) - error ("incomplete type `%T' used in nested name " - "specifier", - scope); - else if (scope != global_namespace) - error ("`%D' is not a member of `%D'", - id_expression, scope); - else - error ("`::%D' has not been declared", id_expression); + was not a dependent type. That is always an + error. */ + qualified_name_lookup_error (scope, id_expression); return error_mark_node; } else if (!scope) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2e78e1b95bc..534bd6be9f2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,10 @@ 2003-07-25 Nathan Sidwell - PR 11596 + PR c++/11617 + * g++.dg/template/lookup2.C: New test. + * g++.dg/template/memclass1.C: Remove instantiated from error. + + PR c++/11596 * g++.dg/template/defarg3.C: New test. * g++.dg/ext/packed2.C: Pack member struct too. Explain why. diff --git a/gcc/testsuite/g++.dg/template/lookup2.C b/gcc/testsuite/g++.dg/template/lookup2.C new file mode 100644 index 00000000000..493b807aec9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup2.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Mar 2003 + +// PR 11617: Failed to diagnose missing function. + +struct B {}; + +template void Bar () +{ + T::foo (); // { dg-error "is not a member of" "" } +} + +void Foo () +{ + Bar (); // { dg-error "instantiated" "" } +} diff --git a/gcc/testsuite/g++.dg/template/memclass1.C b/gcc/testsuite/g++.dg/template/memclass1.C index d4ce9695d2a..c49ed724d6f 100644 --- a/gcc/testsuite/g++.dg/template/memclass1.C +++ b/gcc/testsuite/g++.dg/template/memclass1.C @@ -15,4 +15,4 @@ template struct C typedef typename A::template B X; // { dg-error "declared|invalid" } }; -C c; // { dg-error "instantiated" } +C c; -- 2.30.2