[libcxx] r294612 - Fix PR31916 - std::visit rejects visitors accepting lvalue arguments

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 9 11:01:22 PST 2017


Author: ericwf
Date: Thu Feb  9 13:01:22 2017
New Revision: 294612

URL: http://llvm.org/viewvc/llvm-project?rev=294612&view=rev
Log:
Fix PR31916 - std::visit rejects visitors accepting lvalue arguments

A static assertion was misfiring since it checked
is_callable<Visitor, decltype(__variant_alt<T>.value)>. However
the decltype expression doesn't capture the value category as
required. This patch applies extra braces to decltype to fix
that.

Modified:
    libcxx/trunk/include/variant
    libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp

Modified: libcxx/trunk/include/variant
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/variant?rev=294612&r1=294611&r2=294612&view=diff
==============================================================================
--- libcxx/trunk/include/variant (original)
+++ libcxx/trunk/include/variant Thu Feb  9 13:01:22 2017
@@ -578,7 +578,7 @@ private:
     constexpr decltype(auto) operator()(_Alts&&... __alts) const {
       __std_visit_exhaustive_visitor_check<
           _Visitor,
-          decltype(_VSTD::forward<_Alts>(__alts).__value)...>();
+          decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
       return __invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
                                 _VSTD::forward<_Alts>(__alts).__value...);
     }

Modified: libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp?rev=294612&r1=294611&r2=294612&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp Thu Feb  9 13:01:22 2017
@@ -283,9 +283,20 @@ void test_exceptions() {
 #endif
 }
 
+// See http://llvm.org/PR31916
+void test_caller_accepts_nonconst() {
+  struct A {};
+  struct Visitor {
+    void operator()(A&) {}
+  };
+  std::variant<A> v;
+  std::visit(Visitor{}, v);
+}
+
 int main() {
   test_call_operator_forwarding();
   test_argument_forwarding();
   test_constexpr();
   test_exceptions();
+  test_caller_accepts_nonconst();
 }




More information about the cfe-commits mailing list