Commit 22038b2c by Nathan Sidwell Committed by Nathan Sidwell

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) <DECL_STMT case>: Likewise.
	(tsubst_copy_and_build) <COMPONENT_REF case>: 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
parent 6c84c668
2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
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) <DECL_STMT case>: Likewise.
(tsubst_copy_and_build) <COMPONENT_REF case>: Likewise.
* semantics.c (qualified_name_lookup_error): New, broken out of ...
(finish_id_expression): ... here. Use it.
2003-07-25 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de> 2003-07-25 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
* cfns.gperf: Add '%%' delimiter to placate gperf 3.0. * cfns.gperf: Add '%%' delimiter to placate gperf 3.0.
......
...@@ -4159,6 +4159,7 @@ extern tree finish_template_type (tree, tree, int); ...@@ -4159,6 +4159,7 @@ extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool); extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree); extern void finish_member_declaration (tree);
extern void check_multiple_declarators (void); extern void check_multiple_declarators (void);
extern void qualified_name_lookup_error (tree, tree);
extern tree finish_id_expression (tree, tree, tree, extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *, tree *, cp_id_kind *, tree *,
bool, bool, bool *, bool, bool, bool *,
......
...@@ -7150,8 +7150,7 @@ tsubst_qualified_id (tree qualified_id, tree args, ...@@ -7150,8 +7150,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
} }
if (!BASELINK_P (name) && !DECL_P (expr)) if (!BASELINK_P (name) && !DECL_P (expr))
expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
(complain & tf_error) != 0);
if (DECL_P (expr)) if (DECL_P (expr))
check_accessibility_of_qualified_id (expr, check_accessibility_of_qualified_id (expr,
/*object_type=*/NULL_TREE, /*object_type=*/NULL_TREE,
...@@ -7168,7 +7167,9 @@ tsubst_qualified_id (tree qualified_id, tree args, ...@@ -7168,7 +7167,9 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (is_template) if (is_template)
expr = lookup_template_function (expr, template_args); 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 = (adjust_result_of_qualified_name_lookup
(expr, scope, current_class_type)); (expr, scope, current_class_type));
...@@ -7589,12 +7590,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -7589,12 +7590,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{ {
tree scope = DECL_INITIAL (decl); tree scope = DECL_INITIAL (decl);
tree name = DECL_NAME (decl); tree name = DECL_NAME (decl);
tree decl;
scope = tsubst_expr (scope, args, complain, in_decl); scope = tsubst_expr (scope, args, complain, in_decl);
do_local_using_decl (lookup_qualified_name (scope, decl = lookup_qualified_name (scope, name,
name, /*is_type_p=*/0, /*complain=*/false);
/*is_type_p=*/0, if (decl == error_mark_node)
/*complain=*/true)); qualified_name_lookup_error (scope, name);
else
do_local_using_decl (decl);
} }
else else
{ {
...@@ -8252,18 +8256,15 @@ tsubst_copy_and_build (tree t, ...@@ -8252,18 +8256,15 @@ tsubst_copy_and_build (tree t,
scope is. */ scope is. */
tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0); tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
args = TREE_OPERAND (TREE_OPERAND (member, 1), 1); args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
member = lookup_qualified_name (TREE_OPERAND (member, 0), member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl,
tmpl, /*is_type=*/0, /*complain=*/false);
/*is_type=*/0,
/*complain=*/true);
if (BASELINK_P (member)) if (BASELINK_P (member))
BASELINK_FUNCTIONS (member) BASELINK_FUNCTIONS (member)
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member), = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
args); args);
else else
{ {
error ("`%D' is not a member of `%T'", qualified_name_lookup_error (TREE_TYPE (object), tmpl);
tmpl, TREE_TYPE (object));
return error_mark_node; return error_mark_node;
} }
} }
......
...@@ -2248,6 +2248,24 @@ check_multiple_declarators (void) ...@@ -2248,6 +2248,24 @@ check_multiple_declarators (void)
error ("multiple declarators in template declaration"); 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 is a representation of parsed, but unprocessed,
id-expression. (See cp_parser_id_expression for details.) SCOPE, id-expression. (See cp_parser_id_expression for details.) SCOPE,
if non-NULL, is the type or namespace used to explicitly qualify if non-NULL, is the type or namespace used to explicitly qualify
...@@ -2307,17 +2325,9 @@ finish_id_expression (tree id_expression, ...@@ -2307,17 +2325,9 @@ finish_id_expression (tree id_expression,
if (scope && (!TYPE_P (scope) || !dependent_type_p (scope))) if (scope && (!TYPE_P (scope) || !dependent_type_p (scope)))
{ {
/* Qualified name lookup failed, and the qualifying name /* Qualified name lookup failed, and the qualifying name
was not a dependent type. That is always an was not a dependent type. That is always an
error. */ error. */
if (TYPE_P (scope) && !COMPLETE_TYPE_P (scope)) qualified_name_lookup_error (scope, id_expression);
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);
return error_mark_node; return error_mark_node;
} }
else if (!scope) else if (!scope)
......
2003-07-25 Nathan Sidwell <nathan@codesourcery.com> 2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
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/template/defarg3.C: New test.
* g++.dg/ext/packed2.C: Pack member struct too. Explain why. * g++.dg/ext/packed2.C: Pack member struct too. Explain why.
......
// { dg-do compile }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 27 Mar 2003 <nathan@codesourcery.com>
// PR 11617: Failed to diagnose missing function.
struct B {};
template <typename T> void Bar ()
{
T::foo (); // { dg-error "is not a member of" "" }
}
void Foo ()
{
Bar<B> (); // { dg-error "instantiated" "" }
}
...@@ -15,4 +15,4 @@ template <typename T> struct C ...@@ -15,4 +15,4 @@ template <typename T> struct C
typedef typename A<T>::template B<U> X; // { dg-error "declared|invalid" } typedef typename A<T>::template B<U> X; // { dg-error "declared|invalid" }
}; };
C<void> c; // { dg-error "instantiated" } C<void> c;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment