aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-05-28 02:21:30 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-05-28 02:21:30 +0000
commit81ae598bbd9f3faa1f0d7e16acfba9e6c914f94c (patch)
tree2c493fd519439e6384e6dab99f5bf53a36dada1a
parented3d0b14125f1ff9f29d6cb14f6734ceeed6f622 (diff)
downloadgcc-81ae598bbd9f3faa1f0d7e16acfba9e6c914f94c.zip
gcc-81ae598bbd9f3faa1f0d7e16acfba9e6c914f94c.tar.gz
gcc-81ae598bbd9f3faa1f0d7e16acfba9e6c914f94c.tar.bz2
re PR c++/21614 (wrong code when calling member function of undefined class)
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c23
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/expr/ptrmem6.C12
-rw-r--r--gcc/testsuite/g++.dg/expr/ptrmem6a.C9
5 files changed, 49 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2a9b216..24dc958 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 464b8ef..73bb514 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index efeae61..a6d54b3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..0c75385
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/ptrmem6.C
@@ -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
index 0000000..8dad81c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/ptrmem6a.C
@@ -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;