aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c83
1 files changed, 37 insertions, 46 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e3f4544..694ac0b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5025,6 +5025,7 @@ resolve_address_of_overloaded_function (target_type,
are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
interoperability with most_specialized_instantiation. */
tree matches = NULL_TREE;
+ tree fn;
/* By the time we get here, we should be seeing only real
pointer-to-member types, not the internal POINTER_TYPE to
@@ -5212,8 +5213,20 @@ resolve_address_of_overloaded_function (target_type,
return error_mark_node;
}
- /* Good, exactly one match. */
- return TREE_PURPOSE (matches);
+ /* Good, exactly one match. Now, convert it to the correct type. */
+ fn = TREE_PURPOSE (matches);
+
+ if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
+ return build_unary_op (ADDR_EXPR, fn, 0);
+ else
+ {
+ /* The target must be a REFERENCE_TYPE. Above, build_unary_op
+ will mark the function as addressed, but here we must do it
+ explicitly. */
+ mark_addressable (fn);
+
+ return fn;
+ }
}
/* This function will instantiate the type of the expression given in
@@ -5291,33 +5304,31 @@ instantiate_type (lhstype, rhs, complain)
case COMPONENT_REF:
{
tree field = TREE_OPERAND (rhs, 1);
- if (TREE_CODE (field) == TREE_LIST)
- {
- tree function = instantiate_type (lhstype, field, complain);
- if (function == error_mark_node)
- return error_mark_node;
- my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
+ tree r;
+
+ my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
- if (! DECL_STATIC_FUNCTION_P (function))
+ r = instantiate_type (lhstype, field, complain);
+
+ if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
+ {
+ tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
+ tree fn = TREE_VALUE (field);
+ if (TREE_CODE (fn) == OVERLOAD)
+ fn = OVL_FUNCTION (fn);
+ if (TREE_CODE (fn) == FUNCTION_DECL)
{
- tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
- if (TYPE_MAIN_VARIANT (t) == current_class_type)
- t = constructor_name (t);
-
- cp_error ("object-dependent reference to `%D' can only be used in a call",
- function);
- cp_error (" to form a pointer to member function, say `&%T::%D'",
- t, DECL_NAME (function));
- return error_mark_node;
+ cp_error ("object-dependent reference `%E' can only be used in a call",
+ DECL_NAME (fn));
+ cp_error (" to form a pointer to member function, say `&%T::%E'",
+ t, DECL_NAME (fn));
}
-
- mark_used (function);
- return function;
+ else
+ cp_error ("object-dependent reference can only be used in a call");
+ return error_mark_node;
}
-
- /* I could not trigger this code. MvL */
- my_friendly_abort (980326);
- return rhs;
+
+ return r;
}
case OFFSET_REF:
@@ -5469,27 +5480,7 @@ instantiate_type (lhstype, rhs, complain)
return rhs;
case ADDR_EXPR:
- {
- tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
- if (fn == error_mark_node)
- return error_mark_node;
- mark_addressable (fn);
- TREE_OPERAND (rhs, 0) = fn;
- TREE_CONSTANT (rhs) = staticp (fn);
- if (TYPE_PTRMEMFUNC_P (lhstype))
- {
- /* We must use the POINTER_TYPE to METHOD_TYPE on RHS here
- so that build_ptrmemfunc knows that RHS we have is not
- already a pointer-to-member constant. Instead, it is
- just a ADDR_EXPR over a FUNCTION_DECL. */
- TREE_TYPE (rhs) = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
- rhs = build_ptrmemfunc (TREE_TYPE (rhs), rhs, 0);
- }
- else
- /* Here, things our simple; we have exactly what we need. */
- TREE_TYPE (rhs) = lhstype;
- }
- return rhs;
+ return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
case ENTRY_VALUE_EXPR:
my_friendly_abort (184);