aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c27
-rw-r--r--gcc/cp/semantics.c32
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/lookup2.C18
-rw-r--r--gcc/testsuite/g++.dg/template/memclass1.C2
7 files changed, 71 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 703df4b..0ae6496 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+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>
* cfns.gperf: Add '%%' delimiter to placate gperf 3.0.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8f543b4..994298a 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 f91dca0..24c07bb 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 102653a..50c7478 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 2e78e1b..534bd6b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,10 @@
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/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 0000000..493b807
--- /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 <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" "" }
+}
diff --git a/gcc/testsuite/g++.dg/template/memclass1.C b/gcc/testsuite/g++.dg/template/memclass1.C
index d4ce969..c49ed72 100644
--- a/gcc/testsuite/g++.dg/template/memclass1.C
+++ b/gcc/testsuite/g++.dg/template/memclass1.C
@@ -15,4 +15,4 @@ template <typename T> struct C
typedef typename A<T>::template B<U> X; // { dg-error "declared|invalid" }
};
-C<void> c; // { dg-error "instantiated" }
+C<void> c;