C++ PATCH: PR 26534 for 4.1

Mark Mitchell mark@codesourcery.com
Mon May 1 02:18:00 GMT 2006


I've applied this patch for 26534 to the 4.1 branch.  It's simpler and
safer than the mainline version -- but will result in inferior code
since the middle end is not informed as to the actual range of the
bitfield.

Tested on x86_64-unknown-linux-gnu, applied on the 4.1 branch.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-04-30  Mark Mitchell  <mark@codesourcery.com>

	PR c++/26534
	* cp-tree.h (adjust_bitfield_initializer): Declare.
	* typeck.c (build_modify_expr): Use it.
	* typeck2.c (adjust_bitfield_initializer): Define.
	(process_init_constructor_record): Use it.

2006-04-30  Mark Mitchell  <mark@codesourcery.com>

	PR c++/26534
	* g++.dg/opt/bitfield1.C: New test.

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 113399)
+++ gcc/cp/typeck.c	(working copy)
@@ -5630,6 +5630,10 @@ build_modify_expr (tree lhs, enum tree_c
   if (newrhs == error_mark_node)
     return error_mark_node;
 
+  if (TREE_CODE (lhs) == COMPONENT_REF)
+    newrhs = adjust_bitfield_initializer (TREE_OPERAND (lhs, 1),
+					  newrhs);
+
   if (c_dialect_objc () && flag_objc_gc)
     {
       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 113399)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4389,6 +4389,7 @@ extern void complete_type_check_abstract
 extern int abstract_virtuals_error		(tree, tree);
 
 extern tree store_init_value			(tree, tree);
+extern tree adjust_bitfield_initializer         (tree, tree);
 extern tree digest_init				(tree, tree);
 extern tree build_scoped_ref			(tree, tree, tree *);
 extern tree build_x_arrow			(tree);
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 113399)
+++ gcc/cp/typeck2.c	(working copy)
@@ -838,6 +838,28 @@ process_init_constructor_array (tree typ
   return flags;
 }
 
+/* INIT is the initializer for FIELD.  If FIELD is a bitfield, mask
+   INIT so that its range is bounded by that of FIELD.  Returns the
+   (possibly adjusted) initializer.  */
+
+tree
+adjust_bitfield_initializer (tree field, tree init)
+{
+  int width;
+  tree mask;
+
+  if (!DECL_C_BIT_FIELD (field))
+    return init;
+
+  width = tree_low_cst (DECL_SIZE (field), /*pos=*/1);
+  if (width < TYPE_PRECISION (TREE_TYPE (field)))
+    {
+      mask = build_low_bits_mask (TREE_TYPE (field), width);
+      init = cp_build_binary_op (BIT_AND_EXPR, init, mask);
+    }
+  return init;
+}
+
 /* Subroutine of process_init_constructor, which will process an initializer
    INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
    the initializers.  */
@@ -891,6 +913,7 @@ process_init_constructor_record (tree ty
 
 	  gcc_assert (ce->value);
 	  next = digest_init (TREE_TYPE (field), ce->value);
+	  next = adjust_bitfield_initializer (field, next);
 	  ++idx;
 	}
       else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
Index: gcc/testsuite/g++.dg/opt/bitfield1.C
===================================================================
--- gcc/testsuite/g++.dg/opt/bitfield1.C	(revision 0)
+++ gcc/testsuite/g++.dg/opt/bitfield1.C	(revision 0)
@@ -0,0 +1,18 @@
+// PR c++/26534
+// { dg-do run } 
+// { dg-options "-w -O2" }
+ 
+struct X
+{
+  unsigned a:4;
+};
+
+unsigned i;
+
+int main()
+{
+  struct X x = { 63u };
+  i = x.a;
+  if (i != 15)
+    return 1;
+}



More information about the Gcc-patches mailing list