P0704R1 - fixing const-qualified pointers to members
authorJason Merrill <jason@redhat.com>
Tue, 7 Nov 2017 05:30:40 +0000 (00:30 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 7 Nov 2017 05:30:40 +0000 (00:30 -0500)
* typeck2.c (build_m_component_ref): Also accept in lower stds with
a pedwarn.

From-SVN: r254487

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

index 2a6143a..4478880 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-06  Jason Merrill  <jason@redhat.com>
+
+       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  <paolo.carlini@oracle.com>
 
        PR c++/65579
index 39bc97a..e8e1339 100644 (file)
@@ -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 (file)
index 0000000..074c8fe
--- /dev/null
@@ -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" }
+}