aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-11-07 00:30:40 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-11-07 00:30:40 -0500
commit96d155c6968bf7e2eadc61f1a9bbcc0dd5ae899d (patch)
tree80ad4800b9dc233c0da9c8423b1b777716d347b2 /gcc
parent2d041117f1ee47982a2d8a2a9801f2906df2d91f (diff)
downloadgcc-96d155c6968bf7e2eadc61f1a9bbcc0dd5ae899d.zip
gcc-96d155c6968bf7e2eadc61f1a9bbcc0dd5ae899d.tar.gz
gcc-96d155c6968bf7e2eadc61f1a9bbcc0dd5ae899d.tar.bz2
P0704R1 - fixing const-qualified pointers to members
* typeck2.c (build_m_component_ref): Also accept in lower stds with a pedwarn. From-SVN: r254487
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck2.c29
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/ptrmem1a.C24
3 files changed, 49 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2a6143a..4478880 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 39bc97a..e8e1339 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 0000000..074c8fe
--- /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" }
+}