[PATCH] D35661: [clang] Implement P0704: "Fixing const-qualified pointers to members"
Anton Bikineev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 20 00:32:34 PDT 2017
AntonBikineev created this revision.
https://reviews.llvm.org/D35661
Files:
lib/Sema/SemaExprCXX.cpp
test/CXX/expr/expr.mptr.oper/p7-1z.cpp
Index: test/CXX/expr/expr.mptr.oper/p7-1z.cpp
===================================================================
--- test/CXX/expr/expr.mptr.oper/p7-1z.cpp
+++ test/CXX/expr/expr.mptr.oper/p7-1z.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s
+
+struct X { };
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+template<typename T> T prvalue();
+
+// 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 (non-const, C++17) ref-qualifier &.
+// In a ->* expression or 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 &&.
+void test(X *xp, int (X::*pmf)(int), int (X::*l_pmf)(int) &,
+ int (X::*r_pmf)(int) &&, int (X::*cl_pmf)(int) const &,
+ int (X::*cr_pmf)(int) const &&) {
+ // No ref-qualifier.
+ (lvalue<X>().*pmf)(17);
+ (xvalue<X>().*pmf)(17);
+ (prvalue<X>().*pmf)(17);
+ (xp->*pmf)(17);
+
+ // Lvalue ref-qualifier.
+ (lvalue<X>().*l_pmf)(17);
+ (xvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}}
+ (prvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}}
+ (xp->*l_pmf)(17);
+
+ // Rvalue ref-qualifier.
+ (lvalue<X>().*r_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}}
+ (xvalue<X>().*r_pmf)(17);
+ (prvalue<X>().*r_pmf)(17);
+ (xp->*r_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}}
+
+ // Lvalue const ref-qualifier.
+ (lvalue<X>().*cl_pmf)(17);
+ (xvalue<X>().*cl_pmf)(17);
+ (prvalue<X>().*cl_pmf)(17);
+ (xp->*cl_pmf)(17);
+
+ // Rvalue const ref-qualifier.
+ (lvalue<X>().*cr_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} const &&' can only be called on an rvalue}}
+ (xvalue<X>().*cr_pmf)(17);
+ (prvalue<X>().*cr_pmf)(17);
+ (xp->*cr_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} const &&' can only be called on an rvalue}}
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -5178,9 +5178,11 @@
break;
case RQ_LValue:
- if (!isIndirect && !LHS.get()->Classify(Context).isLValue())
- Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
- << RHSType << 1 << LHS.get()->getSourceRange();
+ if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) {
+ if (!getLangOpts().CPlusPlus1z || !Proto->isConst())
+ Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
+ << RHSType << 1 << LHS.get()->getSourceRange();
+ }
break;
case RQ_RValue:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35661.107452.patch
Type: text/x-patch
Size: 3274 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170720/a7ac3a53/attachment.bin>
More information about the cfe-commits
mailing list