From c75a55a8322cbb3115dac839ed68463210da09ab Mon Sep 17 00:00:00 2001
From: nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri, 25 Jul 2003 16:35:20 +0000
Subject: [PATCH] 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69790 138bc75d-0d04-0410-961f-82ee72b054a4
---
 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 703df4babd28..0ae6496ba8a2 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 8f543b4317e2..994298a061ce 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 f91dca03c47e..24c07bbdb24d 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 102653a338eb..50c74780daf4 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 2e78e1b95bce..534bd6be9f24 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 000000000000..493b807aec98
--- /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 d4ce9695d2a5..c49ed724d6f7 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;
-- 
GitLab