diff options
author | Jason Merrill <jason@redhat.com> | 2015-06-19 14:15:36 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-06-19 14:15:36 -0400 |
commit | 62245e6f7ed68c9c387418827612d719fdc63830 (patch) | |
tree | ec1e23a2b80f9dcd9f9bacd8d99ad47ace2e5e56 /gcc | |
parent | 30ac6e80ba51480a0066329338b3ea5dbf423c26 (diff) | |
download | gcc-62245e6f7ed68c9c387418827612d719fdc63830.zip gcc-62245e6f7ed68c9c387418827612d719fdc63830.tar.gz gcc-62245e6f7ed68c9c387418827612d719fdc63830.tar.bz2 |
re PR c++/65880 (Member function issue with argument "pointer to const array of member function pointers")
PR c++/65880
* decl.c (build_ptrmemfunc_type): Check TYPE_GET_PTRMEMFUNC_TYPE after
cv-qualifiers.
* typeck.c (merge_types): build_ptrmemfunc_type before applying
quals and attributes.
From-SVN: r224678
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 14 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/overload/pmf3.C | 70 |
4 files changed, 88 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2f5e0fa..7d42381 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2015-06-19 Jason Merrill <jason@redhat.com> + PR c++/65880 + * decl.c (build_ptrmemfunc_type): Check TYPE_GET_PTRMEMFUNC_TYPE after + cv-qualifiers. + * typeck.c (merge_types): build_ptrmemfunc_type before applying + quals and attributes. + PR c++/65973 * constexpr.c (build_constexpr_constructor_member_initializers): Handle an empty STATEMENT_LIST. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c102a4e..515c2d3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8224,13 +8224,6 @@ build_ptrmemfunc_type (tree type) if (type == error_mark_node) return type; - /* If a canonical type already exists for this type, use it. We use - this method instead of type_hash_canon, because it only does a - simple equality check on the list of field members. */ - - if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) - return t; - /* Make sure that we always have the unqualified pointer-to-member type first. */ if (cp_cv_quals quals = cp_type_quals (type)) @@ -8239,6 +8232,13 @@ build_ptrmemfunc_type (tree type) return cp_build_qualified_type (unqual, quals); } + /* If a canonical type already exists for this type, use it. We use + this method instead of type_hash_canon, because it only does a + simple equality check on the list of field members. */ + + if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) + return t; + t = make_node (RECORD_TYPE); /* Let the front end know this is a pointer to member function. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c33ffd5..22fbb6e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -786,15 +786,16 @@ merge_types (tree t1, tree t2) int quals = cp_type_quals (t1); if (code1 == POINTER_TYPE) - t1 = build_pointer_type (target); + { + t1 = build_pointer_type (target); + if (TREE_CODE (target) == METHOD_TYPE) + t1 = build_ptrmemfunc_type (t1); + } else t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1)); t1 = build_type_attribute_variant (t1, attributes); t1 = cp_build_qualified_type (t1, quals); - if (TREE_CODE (target) == METHOD_TYPE) - t1 = build_ptrmemfunc_type (t1); - return t1; } diff --git a/gcc/testsuite/g++.dg/overload/pmf3.C b/gcc/testsuite/g++.dg/overload/pmf3.C new file mode 100644 index 0000000..a71f554 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/pmf3.C @@ -0,0 +1,70 @@ +// PR c++/65880 + +class Test +{ + public: + Test(); + ~Test(); + + bool barl(void); + + private: + bool fool(bool (Test::* const *fms)(void)); + bool foo(void); + bool bar(void); +}; + +Test::Test() +{ +} + +Test::~Test() +{ +} + +bool Test::fool(bool (Test::* const *fms)(void)) +{ + bool retval = false; + + int i = 0; + bool (Test::*f)(void) = fms[i++]; + + while (f) { + retval = (this->*f)(); + if (retval) break; + f = fms[i++]; + } + + return retval; +} + + +bool Test::barl(void) +{ + static bool (Test::* const fms[])(void) = { + &Test::foo, + &Test::bar, + 0 + }; + + + + return fool(fms); +} + + +bool Test::foo(void) +{ + return false; +} + +bool Test::bar(void) +{ + return true; +} + +int main(int argc, const char *argv[]) +{ + Test t; + return t.barl(); +} |