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]

fix middle-end/19689


Obvious what the problem is once you look at the test case.  Ho hum.


r~


        PR middle-end/19689
        * expr.c (store_field): Don't strip sub-mode cast when the input
        data is even smaller.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.777
diff -u -p -r1.777 expr.c
--- expr.c	30 Jan 2005 02:13:45 -0000	1.777
+++ expr.c	30 Jan 2005 02:31:19 -0000
@@ -5226,12 +5226,18 @@ store_field (rtx target, HOST_WIDE_INT b
 	 the field we're storing into, that mask is redundant.  This is
 	 particularly common with bit field assignments generated by the
 	 C front end.  */
-      if (TREE_CODE (exp) == NOP_EXPR
-	  && INTEGRAL_TYPE_P (TREE_TYPE (exp))
-	  && (TYPE_PRECISION (TREE_TYPE (exp))
-	      < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp))))
-	  && bitsize == TYPE_PRECISION (TREE_TYPE (exp)))
-	exp = TREE_OPERAND (exp, 0);
+      if (TREE_CODE (exp) == NOP_EXPR)
+	{
+	  tree type = TREE_TYPE (exp);
+	  if (INTEGRAL_TYPE_P (type)
+	      && TYPE_PRECISION (type) < GET_MODE_BITSIZE (TYPE_MODE (type))
+	      && bitsize == TYPE_PRECISION (type))
+	    {
+	      type = TREE_TYPE (TREE_OPERAND (exp, 0));
+	      if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) >= bitsize)
+		exp = TREE_OPERAND (exp, 0);
+	    }
+	}
 
       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
 
Index: testsuite/gcc.c-torture/execute/pr19689.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/pr19689.c
diff -N testsuite/gcc.c-torture/execute/pr19689.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/pr19689.c	30 Jan 2005 02:31:19 -0000
@@ -0,0 +1,19 @@
+extern void abort (void);
+
+struct
+{
+  int b : 29;
+} f;
+
+void foo (short j)
+{
+  f.b = j;
+}
+
+int main()
+{
+  foo (-55);
+  if (f.b != -55)
+    abort ();
+  return 0;
+}


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