diff mbox

C++ PATCH for c++/56235 (wrong error with bit-field and move constructor)

Message ID 5113D551.6040404@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 7, 2013, 4:24 p.m. UTC
Converting a bit-field reference from lvalue to xvalue obscures its 
unlowered type, and isn't useful for scalars anyway.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 4351fe77d1cc018b9f84cbc775489336fb295fb5
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Feb 7 11:06:19 2013 -0500

    	PR c++/56235
    	* method.c (do_build_copy_constructor): Don't bother turning
    	scalars from lvalues to xvalues.
    	(do_build_copy_assign): Likewise.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d13a0cf..a1bab95 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -610,7 +610,9 @@  do_build_copy_constructor (tree fndecl)
 	    }
 
 	  init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
-	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE)
+	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
+	      && !scalarish_type_p (expr_type))
 	    init = move (init);
 	  init = build_tree_list (NULL_TREE, init);
 
@@ -724,7 +726,9 @@  do_build_copy_assign (tree fndecl)
 	  expr_type = cp_build_qualified_type (expr_type, quals);
 
 	  init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
-	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE)
+	  if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE
+	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
+	      && !scalarish_type_p (expr_type))
 	    init = move (init);
 
 	  if (DECL_NAME (field))
diff --git a/gcc/testsuite/g++.dg/init/bitfield4.C b/gcc/testsuite/g++.dg/init/bitfield4.C
new file mode 100644
index 0000000..30041c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/bitfield4.C
@@ -0,0 +1,24 @@ 
+// PR c++/56235
+
+struct A
+{
+  A (const A &);
+};
+
+struct B
+{
+  A a;
+  enum Mode { };
+  Mode m:8;
+};
+
+struct C
+{
+  C();
+  B b;
+};
+
+C fn()
+{
+  return C();
+}