From: Jakub Jelinek Date: Fri, 6 Oct 2017 15:43:17 +0000 (+0200) Subject: P0704R1 - fixing const-qualified pointers to members X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=681f18d19b56527329fc80e5fdb8ef534978f705;p=gcc.git P0704R1 - fixing const-qualified pointers to members 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. From-SVN: r253494 --- 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 + + 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 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 + + P0704R1 - fixing const-qualified pointers to members + * g++.dg/cpp2a/ptrmem1.C: New test. + 2017-10-06 Martin Liska * 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" } +}