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]

[PATCH] PR17913:[4.0 Regression] ICE jumping into statement expression


Hi,

The following patch fix PR17913. The patch does the following:
if the first operator of the conditional_expr is constant and
the not relevant side of it contains label, the conditional_expr
can't be reduced.

The patch was bootstraped and regtested without regressions on
i686-linux.

OK?

br,
   Gabor Loki




2004-10-27 Gabor Loki <loki@inf.u-szeged.hu>


	* c-types.c (build_conditional_expr): Expand the condition of
	reducing conditional_expr.
	* fold.c (fold): Same.
	* tree.c (contains_tree_code): New function.
	* tree.h (contains_tree_code): Prototype added.

Index: gcc/gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.640
diff -u -r1.640 tree.h
--- gcc/gcc/tree.h	22 Oct 2004 18:52:19 -0000	1.640
+++ gcc/gcc/tree.h	27 Oct 2004 11:38:36 -0000
@@ -3799,6 +3799,10 @@
 extern tree walk_tree (tree*, walk_tree_fn, void*, struct pointer_set_t*);
 extern tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
 
+/* Callback for walk_tree, searching for a specific tree type.  */
+
+extern tree contains_tree_code (tree*, int*, void*);
+
 /* In tree-dump.c */
 
 /* Different tree dump places.  When you add new tree dump places,
Index: gcc/gcc/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.439
diff -u -r1.439 tree.c
--- gcc/gcc/tree.c	21 Oct 2004 16:29:51 -0000	1.439
+++ gcc/gcc/tree.c	27 Oct 2004 11:39:23 -0000
@@ -4829,6 +4829,16 @@
     }
 }
 
+/* Callback for walk_tree, look for TREE_CODE which is stored in DATA.  */
+
+tree 
+contains_tree_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
+{
+  if (TREE_CODE(*tp) == *((enum tree_code *)data))
+    return *tp;
+  return NULL_TREE;
+}
+
 /* Subprogram of following function.  Called by walk_tree.
 
    Return *TP if it is an automatic variable or parameter of the
Index: gcc/gcc/fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.468
diff -u -r1.468 fold-const.c
--- gcc/gcc/fold-const.c	11 Oct 2004 03:42:00 -0000	1.468
+++ gcc/gcc/fold-const.c	27 Oct 2004 11:40:01 -0000
@@ -8751,12 +8751,20 @@
 	 so all simple results must be passed through pedantic_non_lvalue.  */
       if (TREE_CODE (arg0) == INTEGER_CST)
 	{
+	  enum tree_code data = LABEL_DECL; 
+         tree unused_op = TREE_OPERAND (t, (integer_zerop (arg0) ? 1 :  2));
 	  tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+      
+          /* Check that the unused operand conatins LABEL_DECL.  */
+          unused_op = walk_tree(&unused_op, contains_tree_code , &data, NULL);
+          
 	  /* Only optimize constant conditions when the selected branch
 	     has the same type as the COND_EXPR.  This avoids optimizing
-	     away "c ? x : throw", where the throw has a void type.  */
-	  if (! VOID_TYPE_P (TREE_TYPE (tem))
-	      || VOID_TYPE_P (type))
+	     away "c ? x : throw", where the throw has a void type.
+	     Avoid throwing away that operand which contains label.  */
+	  if (!unused_op 
+	      && (! VOID_TYPE_P (TREE_TYPE (tem))
+	         || VOID_TYPE_P (type)))
 	    return pedantic_non_lvalue (tem);
 	  return t;
 	}
Index: gcc/gcc/c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.392
diff -u -r1.392 c-typeck.c
--- gcc/gcc/c-typeck.c	17 Oct 2004 22:01:19 -0000	1.392
+++ gcc/gcc/c-typeck.c	27 Oct 2004 11:40:39 -0000
@@ -3040,7 +3040,17 @@
     op2 = convert_and_check (result_type, op2);
 
   if (TREE_CODE (ifexp) == INTEGER_CST)
-    return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
+    {
+      enum tree_code data = LABEL_DECL; 
+      tree unused_op = integer_zerop (ifexp) ? op1 :  op2;
+      
+      /* Check that the unused operand conatins LABEL_DECL.  */
+      unused_op = walk_tree(&unused_op, contains_tree_code , &data, NULL);
+      
+      /* Avoid throwing away that operand which contains label.  */
+      if (!unused_op)
+        return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
+    }
 
   return fold (build3 (COND_EXPR, result_type, ifexp, op1, op2));
 }


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