]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/21614 (wrong code when calling member function of undefined class)
authorMark Mitchell <mark@codesourcery.com>
Sat, 28 May 2005 02:21:30 +0000 (02:21 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 28 May 2005 02:21:30 +0000 (02:21 +0000)
PR c++/21614
* typeck.c (get_member_function_from_ptrfunc): Do not attempt
conversions to base classes of incomplete types.

PR c++/21614
* g++.dg/expr/ptrmem6.C: New test.
* g++.dg/expr/ptrmem6a.C: Likewise.

From-SVN: r100291

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/ptrmem6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/ptrmem6a.C [new file with mode: 0644]

index 2a9b21681226b2559277e3f48561ed184e9281ff..24dc95819b6fb29ac23be37e4728677705bd9fe4 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-27  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/21614
+       * typeck.c (get_member_function_from_ptrfunc): Do not attempt
+       conversions to base classes of incomplete types.
+
 2005-05-27  Ian Lance Taylor  <ian@airs.com>
 
        * semantics.c (add_stmt): Add C++ frontend specific version.
index 464b8efd3fa2dd6854f02bc88f74f196508801b7..73bb514f4992b008875105fa37edf45bafefe348 100644 (file)
@@ -2346,14 +2346,23 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
          gcc_unreachable ();
        }
 
-      /* Convert down to the right base before using the instance.  First
-         use the type...  */
+      /* Convert down to the right base before using the instance.  A
+        special case is that in a pointer to member of class C, C may
+        be incomplete.  In that case, the function will of course be
+        a member of C, and no conversion is required.  In fact,
+        lookup_base will fail in that case, because incomplete
+        classes do not have BINFOs.  */ 
       basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
-      basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
-                             basetype, ba_check, NULL);
-      instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1);
-      if (instance_ptr == error_mark_node)
-       return error_mark_node;
+      if (!same_type_ignoring_top_level_qualifiers_p 
+         (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
+       {
+         basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
+                                 basetype, ba_check, NULL);
+         instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 
+                                         1);
+         if (instance_ptr == error_mark_node)
+           return error_mark_node;
+       }
       /* ...and then the delta in the PMF.  */
       instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
                             instance_ptr, delta);
index efeae615a679e138d935c101bb3ae9301ddf0fdb..a6d54b3a4fca94c809ad23eb7c6bbe9e3c45b287 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-27  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/21614
+       * g++.dg/expr/ptrmem6.C: New test.
+       * g++.dg/expr/ptrmem6a.C: Likewise.
+
 2005-05-27  Kazu Hirata  <kazu@cs.umass.edu>
 
        PR tree-optimization/21658
diff --git a/gcc/testsuite/g++.dg/expr/ptrmem6.C b/gcc/testsuite/g++.dg/expr/ptrmem6.C
new file mode 100644 (file)
index 0000000..0c75385
--- /dev/null
@@ -0,0 +1,12 @@
+// PR C++/21614
+// { dg-additional-sources "ptrmem6a.C" }
+// { dg-do run }
+
+extern struct Z *p; 
+extern int (Z::*m) (); 
+int main () { 
+  if ((p->*m)() == 7)
+    return 0;
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/expr/ptrmem6a.C b/gcc/testsuite/g++.dg/expr/ptrmem6a.C
new file mode 100644 (file)
index 0000000..8dad81c
--- /dev/null
@@ -0,0 +1,9 @@
+struct Z {
+  int f();
+};
+
+int Z::f() { return 7; }
+
+struct Z z;
+int (Z::*m)() = &Z::f;
+struct Z*p = &z;