This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH for PTRMEM_CSTs



This patch fixes another optimization regression with PTRMEM_CSTs,
pointed out by David Edelsohn.  David, I'd appreciate it if you would
verify that this fixes your problem on your systems.

I've also looked through the rest of the pointer-to-member-function
handling code, and I'm pretty sure that we've now caught all the
cases, but one never knows for sure.

I've checked this in on both the mainline and the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-05-21  Mark Mitchell  <mark@codesourcery.com>

	* typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to
	reveal optimization opportunities.

Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.165
diff -u -p -r1.165 typeck.c
--- typeck.c	1999/05/20 17:19:29	1.165
+++ typeck.c	1999/05/21 22:29:38
@@ -6515,15 +6515,15 @@ build_ptrmemfunc (type, pfn, force)
      tree type, pfn;
      int force;
 {
-  tree idx = integer_zero_node;
-  tree delta = integer_zero_node;
-  tree delta2 = integer_zero_node;
-  tree npfn = NULL_TREE;
   tree fn;
   
   /* Handle multiple conversions of pointer to member functions.  */
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
     {
+      tree idx = integer_zero_node;
+      tree delta = integer_zero_node;
+      tree delta2 = integer_zero_node;
+      tree npfn = NULL_TREE;
       tree ndelta, ndelta2;
       tree e1, e2, e3, n;
       tree pfn_type;
@@ -6537,18 +6537,42 @@ build_ptrmemfunc (type, pfn, force)
 	  && comp_target_types (type, pfn_type, 1) != 1)
 	cp_error ("conversion to `%T' from `%T'", type, pfn_type);
 
-      ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));
-      ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn));
-      idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
+      if (TREE_CODE (pfn) == PTRMEM_CST)
+	{
+	  /* We could just build the resulting CONSTRUCTOR now, but we
+	     don't, relying on the general machinery below, together
+	     with constant-folding, to do the right thing.  We don't
+	     want to return a PTRMEM_CST here, even though we could,
+	     because a pointer-to-member constant ceases to be a
+	     constant (from the point of view of the language) when it
+	     is cast to another type.  */
+
+	  expand_ptrmemfunc_cst (pfn, &ndelta, &idx, &npfn, &ndelta2);
+	  if (npfn)
+	    /* This constant points to a non-virtual function.
+	       NDELTA2 will be NULL, but it's value doesn't really
+	       matter since we won't use it anyhow.  */
+	    ndelta2 = integer_zero_node;
+	}
+      else
+	{
+	  ndelta = cp_convert (ptrdiff_type_node, 
+			       build_component_ref (pfn, 
+						    delta_identifier, 
+						    NULL_TREE, 0));
+	  ndelta2 = cp_convert (ptrdiff_type_node, 
+				DELTA2_FROM_PTRMEMFUNC (pfn));
+	  idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
+	}
 
       n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)),
 				TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
 				force);
-
       delta = build_binary_op (PLUS_EXPR, ndelta, n);
       delta2 = build_binary_op (PLUS_EXPR, ndelta2, n);
       e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node));
 	  
+      /* If it's a virtual function, this is what we want.  */
       e2 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx,
 			      NULL_TREE, delta2);
 
@@ -6556,8 +6580,10 @@ build_ptrmemfunc (type, pfn, force)
       npfn = build1 (NOP_EXPR, type, pfn);
       TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn);
 
-      e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, npfn,
-			      NULL_TREE);
+      /* But if it's a non-virtual function, or NULL, we use this
+	 instead.  */
+      e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta,
+			      idx, npfn, NULL_TREE);
       return build_conditional_expr (e1, e2, e3);
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]