diff options
author | Mark Mitchell <mmitchell@gcc.gnu.org> | 1998-02-12 14:51:57 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchell@gcc.gnu.org> | 1998-02-12 14:51:57 +0000 |
commit | 9ca21c0adb7d4de79d72a402914a71bcd38df3a2 (patch) | |
tree | 9a7a43a23bf4f6a78f7e9d2d046f40f3af4dce1a /gcc | |
parent | 614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede (diff) | |
download | gcc-9ca21c0adb7d4de79d72a402914a71bcd38df3a2.zip gcc-9ca21c0adb7d4de79d72a402914a71bcd38df3a2.tar.gz gcc-9ca21c0adb7d4de79d72a402914a71bcd38df3a2.tar.bz2 |
typeck.c (build_ptrmemfunc): Typecheck pointer-to-member conversions.
* typeck.c (build_ptrmemfunc): Typecheck pointer-to-member
conversions.
From-SVN: r17874
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/typeck.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p10769a.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p10769b.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C | 15 |
4 files changed, 29 insertions, 12 deletions
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 +} |