diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-05-28 02:21:30 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-05-28 02:21:30 +0000 |
commit | 81ae598bbd9f3faa1f0d7e16acfba9e6c914f94c (patch) | |
tree | 2c493fd519439e6384e6dab99f5bf53a36dada1a /gcc | |
parent | ed3d0b14125f1ff9f29d6cb14f6734ceeed6f622 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/ptrmem6.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/ptrmem6a.C | 9 |
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; |