diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f290053f278..5d70567db7cc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2005-05-27 Nathan Sidwell + PR c++/21455 + * typeck.c (get_delta_difference): Cope with incomplete but equal + classes. Reorder if. + PR c++/21681 * parser.c (cp_parser_late_parsing_for_member): Disable access checking for template functions. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 8bd101295fd4..92bbc1e071c2 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5523,7 +5523,6 @@ get_delta_difference (tree from, tree to, bool c_cast_p) { tree binfo; - tree virt_binfo; base_kind kind; tree result; @@ -5532,36 +5531,14 @@ get_delta_difference (tree from, tree to, binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind); if (kind == bk_inaccessible || kind == bk_ambig) error (" in pointer to member function conversion"); - else if (!binfo) + else if (binfo) { - if (!allow_inverse_p) - { - error_not_base_type (from, to); - error (" in pointer to member conversion"); - } - else - { - binfo = lookup_base (from, to, c_cast_p ? ba_unique : ba_check, - &kind); - if (binfo) - { - virt_binfo = binfo_from_vbase (binfo); - if (virt_binfo) - /* This is a reinterpret cast, we choose to do nothing. */ - warning (0, "pointer to member cast via virtual base %qT", - BINFO_TYPE (virt_binfo)); - else - result = size_diffop (size_zero_node, BINFO_OFFSET (binfo)); - } - } - } - else - { - virt_binfo = binfo_from_vbase (binfo); - if (!virt_binfo) + if (kind != bk_via_virtual) result = BINFO_OFFSET (binfo); else { + tree virt_binfo = binfo_from_vbase (binfo); + /* This is a reinterpret cast, we choose to do nothing. */ if (allow_inverse_p) warning (0, "pointer to member cast via virtual base %qT", @@ -5571,6 +5548,30 @@ get_delta_difference (tree from, tree to, BINFO_TYPE (virt_binfo)); } } + else if (same_type_ignoring_top_level_qualifiers_p (from, to)) + /* Pointer to member of incomplete class is permitted*/; + else if (!allow_inverse_p) + { + error_not_base_type (from, to); + error (" in pointer to member conversion"); + } + else + { + binfo = lookup_base (from, to, c_cast_p ? ba_unique : ba_check, &kind); + if (binfo) + { + if (kind != bk_via_virtual) + result = size_diffop (size_zero_node, BINFO_OFFSET (binfo)); + else + { + /* This is a reinterpret cast, we choose to do nothing. */ + tree virt_binfo = binfo_from_vbase (binfo); + + warning (0, "pointer to member cast via virtual base %qT", + BINFO_TYPE (virt_binfo)); + } + } + } return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node, result)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c424bf5f0a1c..1a6bdc7ddf6a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-05-27 Nathan Sidwell + PR c++/21455 + * g++.dg/inherit/ptrmem3.C: New. + PR c++/21681 * g++.dg/parse/template16.C: New. diff --git a/gcc/testsuite/g++.dg/inherit/ptrmem3.C b/gcc/testsuite/g++.dg/inherit/ptrmem3.C new file mode 100644 index 000000000000..0c06c65df204 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/ptrmem3.C @@ -0,0 +1,17 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 May 2005 + +// Origin:Andrew Pinski pinskia@gcc.gnu.org +// PR 21455 bogus error with pointer to member of incomplete + +class XMLFile; + +typedef bool (XMLFile::*ParserFunctionPtr)(); + +struct ParserElement +{ + ParserFunctionPtr getPreFunc() const { return preFunc; } + ParserFunctionPtr getPostFunc() const { return postFunc; } + ParserFunctionPtr preFunc; + ParserFunctionPtr postFunc; +};