From 5753ddf9a0c4d180430d838d0fd1707129689aeb Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 7 Nov 2017 05:30:40 +0000 Subject: [PATCH] P0704R1 - fixing const-qualified pointers to members * typeck2.c (build_m_component_ref): Also accept in lower stds with a pedwarn. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254487 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/typeck2.c | 29 +++++++++++++++++++---------- gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2a6143a2f47..44788808193 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-11-06 Jason Merrill + + P0704R1 - fixing const-qualified pointers to members + * typeck2.c (build_m_component_ref): Also accept in lower stds with + a pedwarn. + 2017-11-06 Paolo Carlini PR c++/65579 diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 39bc97a2869..e8e13395431 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1922,17 +1922,26 @@ 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) - && (cxx_dialect < cxx2a - || ((type_memfn_quals (type) - & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) - != TYPE_QUAL_CONST))) + else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type)) { - if (complain & tf_error) - error ("pointer-to-member-function type %qT requires an lvalue", - ptrmem_type); - return error_mark_node; + if ((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", ptrmem_type); + return error_mark_node; + } + else if (cxx_dialect < cxx2a) + { + if (complain & tf_warning_or_error) + pedwarn (input_location, OPT_Wpedantic, + "pointer-to-member-function type %qT requires " + "an lvalue before C++2a", ptrmem_type); + else + return error_mark_node; + } } } return build2 (OFFSET_REF, type, datum, component); diff --git a/gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C b/gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C new file mode 100644 index 00000000000..074c8fe5e3a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C @@ -0,0 +1,24 @@ +// P0704R1 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +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)(); + (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" } +} -- 2.11.4.GIT