Commit 9ca21c0a by Mark Mitchell

typeck.c (build_ptrmemfunc): Typecheck pointer-to-member conversions.

	* typeck.c (build_ptrmemfunc): Typecheck pointer-to-member
	conversions.

From-SVN: r17874
parent 614bb5d4
...@@ -6428,16 +6428,22 @@ build_ptrmemfunc (type, pfn, force) ...@@ -6428,16 +6428,22 @@ build_ptrmemfunc (type, pfn, force)
{ {
tree ndelta, ndelta2; tree ndelta, ndelta2;
tree e1, e2, e3, n; tree e1, e2, e3, n;
tree pfn_type;
/* Is is already the right type? */ /* Is is already the right type? */
if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn))) if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))
return pfn; return pfn;
pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn));
if (!force
&& comp_target_types (type, pfn_type, 0) != 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)); 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)); ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn));
idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0); idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))), n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)),
TYPE_METHOD_BASETYPE (TREE_TYPE (type)), TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
force); force);
...@@ -6471,20 +6477,16 @@ build_ptrmemfunc (type, pfn, force) ...@@ -6471,20 +6477,16 @@ build_ptrmemfunc (type, pfn, force)
&& TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST)) && TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST))
return instantiate_type (type, pfn, 1); return instantiate_type (type, pfn, 1);
if (!force
&& comp_target_types (type, TREE_TYPE (pfn), 0) != 1)
cp_error ("conversion to `%T' from `%T'", type, TREE_TYPE (pfn));
/* Allow pointer to member conversions here. */ /* Allow pointer to member conversions here. */
delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))), delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))),
TYPE_METHOD_BASETYPE (TREE_TYPE (type)), TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
force); force);
delta2 = build_binary_op (PLUS_EXPR, delta2, delta, 1); delta2 = build_binary_op (PLUS_EXPR, delta2, delta, 1);
#if 0
/* We need to check the argument types to see if they are compatible
(any const or volatile violations. */
something like this:
comptype (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (type))),
TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))), ?);
#endif
if (TREE_CODE (TREE_OPERAND (pfn, 0)) != FUNCTION_DECL) if (TREE_CODE (TREE_OPERAND (pfn, 0)) != FUNCTION_DECL)
warning ("assuming pointer to member function is non-virtual"); warning ("assuming pointer to member function is non-virtual");
......
...@@ -28,7 +28,7 @@ dispatch (A *obj, int i, int j) ...@@ -28,7 +28,7 @@ dispatch (A *obj, int i, int j)
void A::main() { void A::main() {
dispatch (&a, 0, 0); dispatch (&a, 0, 0);
void (A::*mPtr)(A*) = &A::f1a; void (A::*mPtr)(A*) = (void (A::*)(A*))&A::f1a;
(*(void (*)(A*))PMF2PF(mPtr))(&a); (*(void (*)(A*))PMF2PF(mPtr))(&a);
(*(void (*)(A*))PMF2PF(f2a))(&a); (*(void (*)(A*))PMF2PF(f2a))(&a);
...@@ -37,7 +37,7 @@ void A::main() { ...@@ -37,7 +37,7 @@ void A::main() {
int main() { int main() {
a.A::main(); a.A::main();
dispatch (&a, 0, 1); dispatch (&a, 0, 1);
void (A::*mPtr)(A*) = &A::f1b; void (A::*mPtr)(A*) = (void (A::*)(A*))&A::f1b;
(*(void (*)(A*))PMF2PF(a.*mPtr))(&a); (*(void (*)(A*))PMF2PF(a.*mPtr))(&a);
(*(void (*)(A*))PMF2PF(a.f2a))(&a); (*(void (*)(A*))PMF2PF(a.f2a))(&a);
......
...@@ -20,6 +20,6 @@ void A::main() { ...@@ -20,6 +20,6 @@ void A::main() {
} }
int main() { int main() {
void (A::*mPtr)(A*) = &A::f1a; void (A::*mPtr)(A*) = (void (A::*)(A*)) &A::f1a;
(*(void (*)(A*))PMF2PF(mPtr))(&a); // ERROR - (*(void (*)(A*))PMF2PF(mPtr))(&a); // ERROR -
} }
class cow {
public:
void moo (char *);
};
void f()
{
cow* c;
void (cow::*fp0)(char*) = &cow::moo; // OK
void (cow::*fp1)(int) = &cow::moo; // ERROR - conversion
int (cow::*fp2)(char*) = &cow::moo; // ERROR - conversion
int (cow::*fp3)(char*, void*) = fp2; // ERROR - conversion
int (cow::*fp4)(double) = (int (cow::*)(double)) fp2; // OK
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment