This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for PTRMEM_CSTs
- To: egcs-patches at egcs dot cygnus dot com
- Subject: C++ PATCH for PTRMEM_CSTs
- From: mark at codesourcery dot com
- Date: Fri, 21 May 1999 15:49:52 -0700
- Cc: David Edelsohn <dje at watson dot ibm dot com>
- Organization: CodeSourcery, LLC
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);
}