diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-10-06 15:43:17 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2017-10-06 15:43:17 +0000 |
commit | 6485490d236f9150b9e19500998ca93bf199bafb (patch) | |
tree | 71e727a3bf21f1fd4ae970fa2bd0c7eb48d4158b /gcc | |
parent | 66174597c84aadf102dfe958eae707bd282e6d65 (diff) |
P0704R1 - fixing const-qualified pointers to members
* typeck2.c (build_m_component_ref): For -std=c++2a allow
pointer to const & qualified method on rvalue.
* g++.dg/cpp2a/ptrmem1.C: New test.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@253494 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/ptrmem1.C | 23 |
4 files changed, 44 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7292fee2d67..e41576dddeb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-10-06 Jakub Jelinek <jakub@redhat.com> + + P0704R1 - fixing const-qualified pointers to members + * typeck2.c (build_m_component_ref): For -std=c++2a allow + pointer to const & qualified method on rvalue. + 2017-10-06 Nathan Sidwell <nathan@acm.org> Use hash_table for extern "C" names diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 82e18ecb178..39bc97a2869 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1908,9 +1908,10 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain) { /* 5.5/6: In a .* expression whose object expression is an rvalue, the program is ill-formed if the second operand is a pointer to member - function with ref-qualifier &. In a .* expression whose object - expression is an lvalue, the program is ill-formed if the second - operand is a pointer to member function with ref-qualifier &&. */ + function with ref-qualifier & (for C++2A: unless its cv-qualifier-seq + is const). In a .* expression whose object expression is an lvalue, + the program is ill-formed if the second operand is a pointer to member + function with ref-qualifier &&. */ if (FUNCTION_REF_QUALIFIED (type)) { bool lval = lvalue_p (datum); @@ -1921,7 +1922,12 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain) ptrmem_type); return error_mark_node; } - else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type)) + else if (!lval + && !FUNCTION_RVALUE_QUALIFIED (type) + && (cxx_dialect < cxx2a + || ((type_memfn_quals (type) + & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) + != TYPE_QUAL_CONST))) { if (complain & tf_error) error ("pointer-to-member-function type %qT requires an lvalue", diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3172683aa4a..7432a3a46e8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-10-06 Jakub Jelinek <jakub@redhat.com> + + P0704R1 - fixing const-qualified pointers to members + * g++.dg/cpp2a/ptrmem1.C: New test. + 2017-10-06 Martin Liska <mliska@suse.cz> * c-c++-common/ubsan/ptr-overflow-sanitization-1.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp2a/ptrmem1.C b/gcc/testsuite/g++.dg/cpp2a/ptrmem1.C new file mode 100644 index 00000000000..d567d088bd4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/ptrmem1.C @@ -0,0 +1,23 @@ +// P0704R1 +// { dg-do compile { target c++11 } } + +struct S { + void ref() & {} + void cref() const& {} + void vref() volatile & {} + void cvref() const volatile & {} +}; + +void +foo () +{ + S{}.ref(); // { dg-error "argument discards qualifiers" } + S{}.cref(); + S{}.vref(); // { dg-error "argument discards qualifiers" } + S{}.cvref(); // { dg-error "argument discards qualifiers" } + + (S{}.*&S::ref)(); // { dg-error "pointer-to-member-function type 'void \\(S::\\*\\)\\(\\) &' requires an lvalue" } + (S{}.*&S::cref)(); // { dg-error "pointer-to-member-function type 'void \\(S::\\*\\)\\(\\) const &' requires an lvalue" "" { target c++17_down } } + (S{}.*&S::vref)(); // { dg-error "pointer-to-member-function type 'void \\(S::\\*\\)\\(\\) volatile &' requires an lvalue" } + (S{}.*&S::cvref)(); // { dg-error "pointer-to-member-function type 'void \\(S::\\*\\)\\(\\) const volatile &' requires an lvalue" } +} |