From 7133357a34e813233a8b949ac335e9521c8b8270 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 21 May 1999 15:42:55 +0000 Subject: [PATCH] typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to reveal optimization opportunities. * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to reveal optimization opportunities. From-SVN: r27084 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/typeck.c | 46 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5337856e549..6ff46de2a62 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 1999-05-21 Mark Mitchell + * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to + reveal optimization opportunities. + * pt.c (tsubst): Don't issue error messages when we're not complaining, even if we see a qualified function type. (check_cv_quals_for_unify): Don't allow a qualified function diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c8c11ca7be7..17147b909f7 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); } -- 2.30.2