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] Fix COND_EXPR genericization fixup (PR c++/37819)


Hi!

As shown on the testcase below, I was wrong with asserting that
COND_EXPR has always a type compatible with
is_bitfield_expr_with_lowered_type if non-NULL.  That's true
during build_conditional_expr, but might not be true afterwards,
because of folding.  Say fold_convert (<char>, COND_EXPR<...>)
will fold the COND_EXPR branches to the new type.  Usually it will
be just an added NOP_EXPR around the bitfield, which is fine for
cp_genericize_r as well as middle-end (then
is_bitfield_expr_with_lowered_type is false and the types are correct).
But, if the type of the bitfield matches the new type during fold
conversion, no NOP_EXPR is added, but is_bitfield_expr_with_lowered_type
is still non-NULL.  The patch below prohibits the fixup if the
type is already correct.

Ok for trunk if bootstrap/regtest passes?

2008-10-14  Jakub Jelinek  <jakub@redhat.com>

	PR c++/37819
	* cp-gimplify.c (cp_genericize_r): Only fold_convert COND_EXPR
	arguments if they don't already have COND_EXPR's type.

	* g++.dg/expr/bitfield11.C: New test.

--- gcc/cp/cp-gimplify.c.jj	2008-10-14 10:17:49.000000000 +0200
+++ gcc/cp/cp-gimplify.c	2008-10-14 10:31:06.000000000 +0200
@@ -815,14 +815,18 @@ cp_genericize_r (tree *stmt_p, int *walk
 	= (TREE_OPERAND (stmt, 2)
 	   ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
 	   : NULL_TREE);
-      if (type_left)
+      if (type_left
+	  && !useless_type_conversion_p (TREE_TYPE (stmt),
+					 TREE_TYPE (TREE_OPERAND (stmt, 1))))
 	{
 	  TREE_OPERAND (stmt, 1)
 	    = fold_convert (type_left, TREE_OPERAND (stmt, 1));
 	  gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
 						 type_left));
 	}
-      if (type_right)
+      if (type_right
+	  && !useless_type_conversion_p (TREE_TYPE (stmt),
+					 TREE_TYPE (TREE_OPERAND (stmt, 2))))
 	{
 	  TREE_OPERAND (stmt, 2)
 	    = fold_convert (type_right, TREE_OPERAND (stmt, 2));
--- gcc/testsuite/g++.dg/expr/bitfield11.C.jj	2008-10-14 10:33:30.000000000 +0200
+++ gcc/testsuite/g++.dg/expr/bitfield11.C	2008-10-14 10:32:14.000000000 +0200
@@ -0,0 +1,13 @@
+// PR c++/37819
+// { dg-do compile }
+
+struct A
+{
+  unsigned int a : 1;
+};
+
+bool
+foo (A *x, A *y)
+{
+  x->a = y ? y->a : true;
+}

	Jakub


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