aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-10-06 15:43:17 +0000
committerJakub Jelinek <jakub@redhat.com>2017-10-06 15:43:17 +0000
commit6485490d236f9150b9e19500998ca93bf199bafb (patch)
tree71e727a3bf21f1fd4ae970fa2bd0c7eb48d4158b /gcc
parent66174597c84aadf102dfe958eae707bd282e6d65 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@253494 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck2.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/ptrmem1.C23
4 files changed, 44 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7292fee2d67..e41576dddeb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 82e18ecb178..39bc97a2869 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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",
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3172683aa4a..7432a3a46e8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..d567d088bd4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/ptrmem1.C
@@ -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" }
+}