This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] C++2A P0704R1 - fixing const-qualified pointers to members


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]