P0704R1 - fixing const-qualified pointers to members
authorJakub Jelinek <jakub@redhat.com>
Fri, 6 Oct 2017 15:43:17 +0000 (17:43 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 6 Oct 2017 15:43:17 +0000 (17:43 +0200)
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

gcc/cp/ChangeLog
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/ptrmem1.C [new file with mode: 0644]

index 7292fee2d6750117f0a142efcadb5a00d493d3ac..e41576dddeb8c395eb9384f65f6511ce34e26d48 100644 (file)
@@ -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
index 82e18ecb17893c0137306c1a4dff2f4f2eb8d408..39bc97a2869c3c83cc463c973a028d270b70f2ce 100644 (file)
@@ -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",
index 3172683aa4a7e2700464af2d2a773f94ee63c80c..7432a3a46e880c54083c25f348da3fb3c7db7a4b 100644 (file)
@@ -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 (file)
index 0000000..d567d08
--- /dev/null
@@ -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" }
+}