[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