aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@gcc.gnu.org>1998-02-12 14:51:57 +0000
committerMark Mitchell <mmitchell@gcc.gnu.org>1998-02-12 14:51:57 +0000
commit9ca21c0adb7d4de79d72a402914a71bcd38df3a2 (patch)
tree9a7a43a23bf4f6a78f7e9d2d046f40f3af4dce1a /gcc
parent614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede (diff)
downloadgcc-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.c20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10769a.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10769b.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C15
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
+}