From 9d363a56a8ff6587f8d32ea380b55fea77ea5f13 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Fri, 19 Mar 2004 01:35:01 +0000
Subject: [PATCH] c-common.c (pointer_int_sum): Do not complain about using
 pointers to pointers-to-members.

	* c-common.c (pointer_int_sum): Do not complain about using
	pointers to pointers-to-members.

	* call.c (build_conditional_expr): Do not call force_rvalue for
	operands of void_type when the conditional expression itself has
	void type.
	* name-lookup.c (pushdecl): Don't consider a declaration of a
	function named "main" to be an overload of a type named "main".
	* parser.c (cp_parser_template_name): Perform name lookup when the
	template name is proceeded by "template" if the qualifying scope
	is non-dependent.
	* typeck.c (composite_pointer_type_r): Correctly handle
	pointer-to-member types.
	(build_const_cast): Likewise.

	* g++.dg/expr/cond5.C: New test.
	* g++.dg/expr/constcast1.C: Likewise.
	* g++.dg/expr/ptrmem2.C: Likewise.
	* g++.dg/expr/ptrmem3.C: Likewise.
	* g++.dg/lookup/main1.C: Likewise.
	* g++.dg/template/lookup6.C: Likewise.

From-SVN: r79663
---
 gcc/ChangeLog                           |  5 +++++
 gcc/c-common.c                          |  6 ------
 gcc/cp/ChangeLog                        | 14 ++++++++++++++
 gcc/cp/call.c                           | 12 +++++++++---
 gcc/cp/name-lookup.c                    |  2 +-
 gcc/cp/parser.c                         | 10 +++++++++-
 gcc/cp/typeck.c                         |  5 +++--
 gcc/testsuite/ChangeLog                 |  9 +++++++++
 gcc/testsuite/g++.dg/lookup/main1.C     |  3 +++
 gcc/testsuite/g++.dg/template/lookup6.C | 11 +++++++++++
 10 files changed, 64 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/main1.C
 create mode 100644 gcc/testsuite/g++.dg/template/lookup6.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d118f05ba5b8..c33d57b54574 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2004-03-18  Mark Mitchell  <mark@codesourcery.com>
+
+	* c-common.c (pointer_int_sum): Do not complain about using
+	pointers to pointers-to-members.
+
 2004-03-18  Kazu Hirata  <kazu@cs.umass.edu>
 
 	* system.h (MD_ASM_CLOBBERS): Move to "Old target macros that
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 057ebeeeaf5e..49c9ccf613cd 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2484,12 +2484,6 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
 	pedwarn ("pointer to member function used in arithmetic");
       size_exp = integer_one_node;
     }
-  else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-	pedwarn ("pointer to a member used in arithmetic");
-      size_exp = integer_one_node;
-    }
   else
     size_exp = size_in_bytes (TREE_TYPE (result_type));
 
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 00e506659b5f..1052abed8af9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2004-03-18  Mark Mitchell  <mark@codesourcery.com>
+
+	* call.c (build_conditional_expr): Do not call force_rvalue for
+	operands of void_type when the conditional expression itself has
+	void type.
+	* name-lookup.c (pushdecl): Don't consider a declaration of a
+	function named "main" to be an overload of a type named "main".
+	* parser.c (cp_parser_template_name): Perform name lookup when the
+	template name is proceeded by "template" if the qualifying scope
+	is non-dependent.
+	* typeck.c (composite_pointer_type_r): Correctly handle
+	pointer-to-member types.
+	(build_const_cast): Likewise.
+
 2004-03-18  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
 	* cp-tree.def (TEMPLATE_TYPE_PARM, TYPEOF_TYPE): Update comments.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 62182f3950ce..7a3039bd3b81 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3178,18 +3178,24 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
 	   type of the other and is an rvalue.
 
 	 --Both the second and the third operands have type void; the
-	   result is of type void and is an rvalue.  */
+	   result is of type void and is an rvalue.  
+
+         We must avoid calling force_rvalue for expressions of type
+	 "void" because it will complain that their value is being
+	 used.   */
       if (TREE_CODE (arg2) == THROW_EXPR 
 	  && TREE_CODE (arg3) != THROW_EXPR)
 	{
-	  arg3 = force_rvalue (arg3);
+	  if (!VOID_TYPE_P (arg3_type))
+	    arg3 = force_rvalue (arg3);
 	  arg3_type = TREE_TYPE (arg3);
 	  result_type = arg3_type;
 	}
       else if (TREE_CODE (arg2) != THROW_EXPR 
 	       && TREE_CODE (arg3) == THROW_EXPR)
 	{
-	  arg2 = force_rvalue (arg2);
+	  if (!VOID_TYPE_P (arg2_type))
+	    arg2 = force_rvalue (arg2);
 	  arg2_type = TREE_TYPE (arg2);
 	  result_type = arg2_type;
 	}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index ce101de168c4..15896821282d 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -706,7 +706,7 @@ pushdecl (tree x)
 
 		  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 		}
-	      else if (DECL_MAIN_P (x))
+	      else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
 		{
 		  /* A redeclaration of main, but not a duplicate of the
 		     previous one.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index db4025251f4d..0dc63cd8d278 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8203,7 +8203,15 @@ cp_parser_template_name (cp_parser* parser,
 	    *is_identifier = true;
 	  return identifier;
 	}
-      if (template_keyword_p)
+
+      /* If the "template" keyword is present, then there is generally
+	 no point in doing name-lookup, so we just return IDENTIFIER.
+	 But, if the qualifying scope is non-dependent then we can
+	 (and must) do name-lookup normally.  */
+      if (template_keyword_p
+	  && (!parser->scope
+	      || (TYPE_P (parser->scope) 
+		  && dependent_type_p (parser->scope))))
 	return identifier;
     }
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 10103c8aecbb..e353d3f57aca 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -443,7 +443,6 @@ composite_pointer_type_r (tree t1, tree t2, const char* location)
   result_type = cp_build_qualified_type (result_type,
 					 (cp_type_quals (pointee1)
 					  | cp_type_quals (pointee2)));
-  result_type = build_pointer_type (result_type);
   /* If the original types were pointers to members, so is the
      result.  */
   if (TYPE_PTR_TO_MEMBER_P (t1))
@@ -456,6 +455,8 @@ composite_pointer_type_r (tree t1, tree t2, const char* location)
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
 				       result_type);
     }
+  else
+    result_type = build_pointer_type (result_type);
 
   /* Merge the attributes.  */
   attributes = (*targetm.merge_type_attributes) (t1, t2);
@@ -4726,7 +4727,7 @@ build_const_cast (tree type, tree expr)
       return t;
     }
 
-  if (!POINTER_TYPE_P (type))
+  if (!POINTER_TYPE_P (type) && !TYPE_PTRMEM_P (type))
     error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
   else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
     {
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b7ff475b02da..be760c89c87c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2004-03-18  Mark Mitchell  <mark@codesourcery.com>
+
+	* g++.dg/expr/cond5.C: New test.
+	* g++.dg/expr/constcast1.C: Likewise.
+	* g++.dg/expr/ptrmem2.C: Likewise.
+	* g++.dg/expr/ptrmem3.C: Likewise.
+	* g++.dg/lookup/main1.C: Likewise.
+	* g++.dg/template/lookup6.C: Likewise.
+
 2004-03-18  Mark Mitchell  <mark@codesourcery.com>
 
 	* gcc.dg/local1.c: New test.
diff --git a/gcc/testsuite/g++.dg/lookup/main1.C b/gcc/testsuite/g++.dg/lookup/main1.C
new file mode 100644
index 000000000000..1de834235a6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/main1.C
@@ -0,0 +1,3 @@
+struct main {};
+
+int main () {}
diff --git a/gcc/testsuite/g++.dg/template/lookup6.C b/gcc/testsuite/g++.dg/template/lookup6.C
new file mode 100644
index 000000000000..2ca6dcc7547d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/lookup6.C
@@ -0,0 +1,11 @@
+struct S
+{
+  template<typename T> static void g();
+};
+
+template<typename T>
+void f() { return S::template g<T>(); }
+
+void g() {
+  f<int>();
+}
-- 
GitLab