[PATCH] D36855: Fixed pointer to const& member function on rvalues, P0704r1

Blitz Rakete via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 18 22:30:56 PDT 2017


Rakete1111 updated this revision to Diff 111800.
Rakete1111 added a comment.

Rebased because another commit already added the definitions of the C++20 groups.


https://reviews.llvm.org/D36855

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExprCXX.cpp
  test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp


Index: test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp
===================================================================
--- test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp
+++ test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify
+
+struct X {
+  void ref() & {}
+  void cref() const& {}
+};
+
+void test() {
+  X{}.ref(); // expected-error{{cannot initialize object parameter of type 'X' with an expression of type 'X'}}
+  X{}.cref(); // expected-no-error
+
+  (X{}.*&X::ref)(); // expected-error{{pointer-to-member function type 'void (X::*)() &' can only be called on an lvalue}}
+  (X{}.*&X::cref)(); // expected-no-error
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -5175,9 +5175,16 @@
       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()) {
+        // C++2a allows functions with ref-qualifier & if they are also 'const'.
+        if (Proto->isConst())
+          Diag(Loc, getLangOpts().CPlusPlus2a
+                        ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue
+                        : diag::ext_pointer_to_const_ref_member_on_rvalue);
+        else
+          Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
+              << RHSType << 1 << LHS.get()->getSourceRange();
+      }
       break;
 
     case RQ_RValue:
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4088,6 +4088,13 @@
 def err_pointer_to_member_oper_value_classify: Error<
   "pointer-to-member function type %0 can only be called on an "
   "%select{rvalue|lvalue}1">;
+def ext_pointer_to_const_ref_member_on_rvalue : Extension<
+  "invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension">,
+  InGroup<CXX2a>;
+def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning<
+  "invoking a pointer to a 'const &' member function on an rvalue is "
+  "incompatible with C++ standards before C++2a">,
+  InGroup<CXXPre2aCompatPedantic>, DefaultIgnore, SFINAEFailure;
 def ext_ms_deref_template_argument: ExtWarn<
   "non-type template argument containing a dereference operation is a "
   "Microsoft extension">, InGroup<MicrosoftTemplate>;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36855.111800.patch
Type: text/x-patch
Size: 2690 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170819/9cb88c1d/attachment.bin>


More information about the cfe-commits mailing list