From 2be3e2ee45dea048104a7e586532605aa950ed1d Mon Sep 17 00:00:00 2001
From: mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 14 Jul 2003 19:05:05 +0000
Subject: [PATCH] 	PR c++/7019 	* cp-tree.h (lookup_qualified_name):
 Adjust prototype. 	* decl.c (lookup_qualified_name): Add complain
 parameter.  Adjust 	call to is_aggr_type. 	* parser.c
 (cp_parser_lookup_name): Adjust call to 	lookup_qualified_name. 	* pt.c
 (tsubst_qualified_id): Likewise. 	(tsubst_copy_and_build): Likewise. 
 * semantics.c (finish_qualified_id_expr): Deal with erroneous 	expressions.

	PR c++/7019
	* g++.dg/template/overload2.C: New test.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69342 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                          | 13 ++++++++++++
 gcc/cp/cp-tree.h                          |  2 +-
 gcc/cp/decl.c                             | 26 ++++++++++++++---------
 gcc/cp/parser.c                           |  3 ++-
 gcc/cp/pt.c                               | 12 ++++++-----
 gcc/cp/semantics.c                        |  3 +++
 gcc/testsuite/ChangeLog                   |  5 +++++
 gcc/testsuite/g++.dg/template/overload2.C | 15 +++++++++++++
 8 files changed, 62 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/overload2.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8318b914020..e84ea849f81 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+2003-07-14  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/7019
+	* cp-tree.h (lookup_qualified_name): Adjust prototype.
+	* decl.c (lookup_qualified_name): Add complain parameter.  Adjust
+	call to is_aggr_type.
+	* parser.c (cp_parser_lookup_name): Adjust call to
+	lookup_qualified_name.
+	* pt.c (tsubst_qualified_id): Likewise.
+	(tsubst_copy_and_build): Likewise.
+	* semantics.c (finish_qualified_id_expr): Deal with erroneous
+	expressions.
+
 2003-07-14  Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 	PR c++/11510
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8658be6d93a..acc4528f9ef 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3679,7 +3679,7 @@ extern tree make_typename_type			(tree, tree, tsubst_flags_t);
 extern tree make_unbound_class_template		(tree, tree, tsubst_flags_t);
 extern tree lookup_name_nonclass		(tree);
 extern tree lookup_function_nonclass            (tree, tree);
-extern tree lookup_qualified_name               (tree, tree, bool);
+extern tree lookup_qualified_name               (tree, tree, bool, bool);
 extern tree lookup_name				(tree, int);
 extern tree lookup_name_current_level		(tree);
 extern tree lookup_type_current_level		(tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d4c212f3e76..2daaee60c0e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5761,10 +5761,12 @@ qualify_lookup (tree val, int flags)
    bindings.  
 
    Returns a DECL (or OVERLOAD, or BASELINK) representing the
-   declaration found.  */
+   declaration found.  If no suitable declaration can be found,
+   ERROR_MARK_NODE is returned.  Iif COMPLAIN is true and SCOPE is
+   neither a class-type nor a namespace a diagnostic is issued.  */
 
 tree
-lookup_qualified_name (tree scope, tree name, bool is_type_p)
+lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
 {
   int flags = 0;
 
@@ -5776,15 +5778,19 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p)
       flags |= LOOKUP_COMPLAIN;
       if (is_type_p)
 	flags |= LOOKUP_PREFER_TYPES;
-      if (!qualified_lookup_using_namespace (name, scope, &binding, 
-					     flags))
-	return NULL_TREE;
-      return select_decl (&binding, flags);
+      if (qualified_lookup_using_namespace (name, scope, &binding, 
+					    flags))
+	return select_decl (&binding, flags);
     }
-  else if (is_aggr_type (scope, /*or_else=*/1))
-    return lookup_member (scope, name, 0, is_type_p);
-  else
-    return error_mark_node;
+  else if (is_aggr_type (scope, complain))
+    {
+      tree t;
+      t = lookup_member (scope, name, 0, is_type_p);
+      if (t)
+	return t;
+    }
+
+  return error_mark_node;
 }
 
 /* Check to see whether or not DECL is a variable that would have been
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 98411a6abdb..bfce0ca8d34 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12825,7 +12825,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
 	     may be instantiated during name lookup.  In that case,
 	     errors may be issued.  Even if we rollback the current
 	     tentative parse, those errors are valid.  */
-	  decl = lookup_qualified_name (parser->scope, name, is_type);
+	  decl = lookup_qualified_name (parser->scope, name, is_type,
+					/*complain=*/true);
 	  if (dependent_p)
 	    pop_scope (parser->scope);
 	}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ee9d2459d7e..1f7822ca72b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7149,9 +7149,9 @@ tsubst_qualified_id (tree qualified_id, tree args,
     }
   else
     expr = name;
-  if (!BASELINK_P (name)
-      && !DECL_P (expr))
-    expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0);
+  if (!BASELINK_P (name) && !DECL_P (expr))
+    expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0,
+				  (complain & tf_error) != 0);
   if (DECL_P (expr))
     check_accessibility_of_qualified_id (expr, 
 					 /*object_type=*/NULL_TREE,
@@ -7611,7 +7611,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	    scope = tsubst_expr (scope, args, complain, in_decl);
 	    do_local_using_decl (lookup_qualified_name (scope,
 							name, 
-							/*is_type_p=*/0));
+							/*is_type_p=*/0,
+							/*complain=*/true));
 	  }
 	else
 	  {
@@ -8285,7 +8286,8 @@ tsubst_copy_and_build (tree t,
 	    args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
 	    member = lookup_qualified_name (TREE_OPERAND (member, 0),
 					    tmpl, 
-					    /*is_type=*/0);
+					    /*is_type=*/0,
+					    /*complain=*/true);
 	    if (BASELINK_P (member))
 	      BASELINK_FUNCTIONS (member) 
 		= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ab9376b48a6..9a9ae20e1be 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1343,6 +1343,9 @@ tree
 finish_qualified_id_expr (tree qualifying_class, tree expr, bool done,
 			  bool address_p)
 {
+  if (error_operand_p (expr))
+    return error_mark_node;
+
   /* If EXPR occurs as the operand of '&', use special handling that
      permits a pointer-to-member.  */
   if (address_p && done)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c279efebd63..9a4b06245eb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-07-14  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/7019
+	* g++.dg/template/overload2.C: New test.
+
 2003-07-14  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 
 	PR optimization/11440
diff --git a/gcc/testsuite/g++.dg/template/overload2.C b/gcc/testsuite/g++.dg/template/overload2.C
new file mode 100644
index 00000000000..253d055cdf6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/overload2.C
@@ -0,0 +1,15 @@
+template <class T, int (T::*)> struct foo;
+
+template <class T>
+int f(foo<T,&T::ob_type>*);
+
+template <class T>
+char* f(...);
+
+struct X { int ob_type; };
+struct Y { char* ob_type; };
+  int x = f<X>(0);
+char* y = f<Y>(0);
+char* z = f<int>(0);
+
+int main() { return 0; }
-- 
GitLab