typeck.c (build_ptrmemfunc): Typecheck pointer-to-member conversions.
authorMark Mitchell <mmitchell@gcc.gnu.org>
Thu, 12 Feb 1998 14:51:57 +0000 (14:51 +0000)
committerMark Mitchell <mmitchell@gcc.gnu.org>
Thu, 12 Feb 1998 14:51:57 +0000 (14:51 +0000)
* typeck.c (build_ptrmemfunc): Typecheck pointer-to-member
conversions.

From-SVN: r17874

gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.mike/p10769a.C
gcc/testsuite/g++.old-deja/g++.mike/p10769b.C
gcc/testsuite/g++.old-deja/g++.other/ptrmem2.C [new file with mode: 0644]

index 7722113..311c4bc 100644 (file)
@@ -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");
 
index 784465c..6bfb80c 100644 (file)
@@ -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);
index 91e11fb..7cc20c5 100644 (file)
@@ -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 (file)
index 0000000..8573095
--- /dev/null
@@ -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
+}