From 9ca21c0adb7d4de79d72a402914a71bcd38df3a2 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 12 Feb 1998 14:51:57 +0000 Subject: typeck.c (build_ptrmemfunc): Typecheck pointer-to-member conversions. * typeck.c (build_ptrmemfunc): Typecheck pointer-to-member conversions. From-SVN: r17874 --- gcc/cp/typeck.c | 20 +++++++++++--------- gcc/testsuite/g++.old-deja/g++.mike/p10769a.C | 4 ++-- gcc/testsuite/g++.old-deja/g++.mike/p10769b.C | 2 +- gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C | 15 +++++++++++++++ 4 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C (limited to 'gcc') diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7722113..311c4bc 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6428,16 +6428,22 @@ build_ptrmemfunc (type, pfn, force) { tree ndelta, ndelta2; tree e1, e2, e3, n; + tree pfn_type; /* Is is already the right type? */ if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (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)); 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 (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))), + n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)), TYPE_METHOD_BASETYPE (TREE_TYPE (type)), force); @@ -6471,20 +6477,16 @@ build_ptrmemfunc (type, pfn, force) && TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST)) 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. */ delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))), TYPE_METHOD_BASETYPE (TREE_TYPE (type)), force); 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) warning ("assuming pointer to member function is non-virtual"); diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C b/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C index 784465c..6bfb80ca 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C @@ -28,7 +28,7 @@ dispatch (A *obj, int i, int j) void A::main() { 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(f2a))(&a); @@ -37,7 +37,7 @@ void A::main() { int main() { a.A::main(); 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.f2a))(&a); diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10769b.C b/gcc/testsuite/g++.old-deja/g++.mike/p10769b.C index 91e11fb..7cc20c5 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p10769b.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p10769b.C @@ -20,6 +20,6 @@ void A::main() { } int main() { - void (A::*mPtr)(A*) = &A::f1a; + void (A::*mPtr)(A*) = (void (A::*)(A*)) &A::f1a; (*(void (*)(A*))PMF2PF(mPtr))(&a); // ERROR - } diff --git a/gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C b/gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C new file mode 100644 index 0000000..8573095 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C @@ -0,0 +1,15 @@ +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 +} -- cgit v1.1