This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to make lambda closures trivially copyable


Jonathan pointed out that lambda closure types were being treated as non-trivially-copyable for no good reason. It seems that this was because I missed this case in my patch a while back to distinguish between deleted and trivial.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit f22332a314c86745cf160ae297ef9d36d30f4cb6
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Oct 10 08:21:10 2014 -0400

    	* method.c (implicitly_declare_fn): Handle deleted lambda default
    	ctor and copy assop here.
    	* class.c (check_bases_and_members): Not here.
    	(add_implicitly_declared_members): And don't set
    	CLASSTYPE_LAZY_MOVE_ASSIGN.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 12ac30a..b661187 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3158,7 +3158,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
       TYPE_HAS_COPY_ASSIGN (t) = 1;
       TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
       CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
-      if (move_ok)
+      if (move_ok && !LAMBDA_TYPE_P (t))
 	CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
     }
 
@@ -5624,13 +5624,6 @@ check_bases_and_members (tree t)
 
   if (LAMBDA_TYPE_P (t))
     {
-      /* "The closure type associated with a lambda-expression has a deleted
-	 default constructor and a deleted copy assignment operator."  */
-      TYPE_NEEDS_CONSTRUCTING (t) = 1;
-      TYPE_HAS_COMPLEX_DFLT (t) = 1;
-      TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
-      CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0;
-
       /* "This class type is not an aggregate."  */
       CLASSTYPE_NON_AGGREGATE (t) = 1;
     }
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 8828986..dce2d2b 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1911,6 +1911,12 @@ implicitly_declare_fn (special_function_kind kind, tree type,
   DECL_DEFAULTED_FN (fn) = 1;
   if (cxx_dialect >= cxx11)
     {
+      /* "The closure type associated with a lambda-expression has a deleted
+	 default constructor and a deleted copy assignment operator."  */
+      if ((kind == sfk_constructor
+	   || kind == sfk_copy_assignment)
+	  && LAMBDA_TYPE_P (type))
+	deleted_p = true;
       DECL_DELETED_FN (fn) = deleted_p;
       DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
     }
diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible4.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible4.C
new file mode 100644
index 0000000..c6d1758
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible4.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+void f()
+{
+  int x;
+  auto l = [=]{ return x; };
+  typedef decltype(l) C;
+  SA(__is_trivially_copyable(C));
+  SA(__is_trivially_constructible(C,C));
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]