This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] C++2A P0704R1 - fixing const-qualified pointers to members
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Nathan Sidwell <nathan at acm dot org>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 19 Sep 2017 15:00:23 +0200
- Subject: [C++ PATCH] C++2A P0704R1 - fixing const-qualified pointers to members
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jakub at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2DDA4A0C12
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
(Sorry for the resent, forgot to CC gcc-patches).
Another easy C++2A patch. Here I wonder if we don't want
a -Wc++2a-compat warning and whether & (const | volatile)) == const
is best (for the case if there are other quals in the future),
or if we just want == const.
For the compat warning, the behavior will be that for c++17 and below
we'll error out or fail SFINAE, for c++2a we'll accept it, so not sure
if it falls into what we want to warn or not.
Regtested on x86_64-linux and i686-linux with make check-c++-all.
2017-09-19 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.
* g++.dg/cpp2a/ptrmem1.C: New test.
--- gcc/cp/typeck2.c.jj 2017-09-19 12:06:30.635052397 +0200
+++ gcc/cp/typeck2.c 2017-09-19 12:12:50.725235890 +0200
@@ -1908,9 +1908,10 @@ build_m_component_ref (tree datum, tree
{
/* 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
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",
--- gcc/testsuite/g++.dg/cpp2a/ptrmem1.C.jj 2017-09-19 12:30:49.344545579 +0200
+++ gcc/testsuite/g++.dg/cpp2a/ptrmem1.C 2017-09-19 12:33:40.831363371 +0200
@@ -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" }
+}
Jakub