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]

Re: Patch for bugs 772 and 17913


Roger Sayle wrote:
-  if (TREE_CODE (ifexp) == INTEGER_CST)
-    return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
-
 return fold (build3 (COND_EXPR, result_type, ifexp, op1, op2));
}

Could you take the opportunity to change the line following your change to use "fold_build3 (COND_EXPR, ...". This is a case where in the past the C front-end duplicated some functionality from fold to avoid creating COND_EXPR nodes when not needed. With the new API(s), letting fold-const.c handle this has a much smaller overhead (in addition to improving correctness).

Ok. I changed it. Bootstraped and regtested without regressions on i686-unknown-linux-gnu.

+static tree contains_label_1 (tree*, int*, void*);
+static bool contains_label_p (tree);

You only need to prototype the constains_label_p call, as it's subroutine contains_label_1 is only used after it's defined. If both these routines were moved earlier in fold-const.c, you wouldn't need to prototype either.

Of course, the prototype of 'contains_label_1' isn't necessary. Personally, I prefer using prototypes in this way, but I can remove it.

br,
   Gabor Loki

---

2005-05-02 Gabor Loki <loki@gcc.gnu.org>

     PR c/17913
     * c-typeck.c (build_conditional_expr): Remove reducing cond_expr.
     * fold-const.c (fold): Expand the condition of reducing cond_expr.
     (contains_label_1, contains_label_p): New functions for checking
     labels in a sub-tree.

testsuite:
2005-05-02  Gabor Loki <loki@gcc.gnu.org>

     PR c/17913
     * gcc.c-torture/compile/pr17913.c: Computed jump test for PR17913

Index: gcc/gcc/c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.439
diff -u -r1.439 c-typeck.c
--- gcc/gcc/c-typeck.c	2 May 2005 16:02:19 -0000	1.439
+++ gcc/gcc/c-typeck.c	3 May 2005 06:41:14 -0000
@@ -3089,10 +3089,7 @@
   if (result_type != TREE_TYPE (op2))
     op2 = convert_and_check (result_type, op2);
 
-  if (TREE_CODE (ifexp) == INTEGER_CST)
-    return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
-
-  return fold (build3 (COND_EXPR, result_type, ifexp, op1, op2));
+  return fold_build3 (COND_EXPR, result_type, ifexp, op1, op2);
 }
 
 /* Return a compound expression that performs two expressions and
Index: gcc/gcc/fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.573
diff -u -r1.573 fold-const.c
--- gcc/gcc/fold-const.c	27 Apr 2005 19:38:57 -0000	1.573
+++ gcc/gcc/fold-const.c	3 May 2005 06:41:14 -0000
@@ -134,6 +134,7 @@
 static tree fold_not_const (tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static bool tree_expr_nonzero_p (tree);
+static bool contains_label_p (tree);
 
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
@@ -9947,12 +9948,16 @@
 	 so all simple results must be passed through pedantic_non_lvalue.  */
       if (TREE_CODE (arg0) == INTEGER_CST)
 	{
+	  tree unused_op = integer_zerop (arg0) ? op1 : op2;
 	  tem = integer_zerop (arg0) ? op2 : op1;
 	  /* 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 ((!TREE_SIDE_EFFECTS (unused_op)
+               || !contains_label_p (unused_op))
+              && (! VOID_TYPE_P (TREE_TYPE (tem))
+                  || VOID_TYPE_P (type)))
 	    return pedantic_non_lvalue (tem);
 	  return NULL_TREE;
 	}
@@ -11592,6 +11597,37 @@
   return true;
 }
 
+/* Callback for walk_tree, looking for LABEL_EXPR.
+   Returns tree TP if it is LABEL_EXPR. Otherwise it returns NULL_TREE.
+   Do not check the sub-tree of GOTO_EXPR.  */
+
+static tree
+contains_label_1 (tree *tp,
+                  int *walk_subtrees,
+                  void *data ATTRIBUTE_UNUSED)
+{
+  switch (TREE_CODE (*tp))
+    {
+    case LABEL_EXPR:
+      return *tp;
+    case GOTO_EXPR:
+      *walk_subtrees = 0;
+    /* no break */
+    default:
+      return NULL_TREE;
+    }
+}
+
+/* Checks wheter the sub-tree ST contains a label LABEL_EXPR which is
+   accessible from outside the sub-tree. Returns NULL_TREE if no
+   addressable label is found.  */
+
+static bool
+contains_label_p (tree st)
+{
+  return (walk_tree (&st, contains_label_1 , NULL, NULL) != NULL_TREE);
+}
+
 /* Simplify the floating point expression EXP when the sign of the
    result is not significant.  Return NULL_TREE if no simplification
    is possible.  */
Index: gcc/gcc/testsuite/gcc.c-torture/compile/pr17913.c
===================================================================
--- /dev/null	2005-03-30 15:21:55.000000000 +0200
+++ gcc/gcc/testsuite/gcc.c-torture/compile/pr17913.c	2005-05-02 14:03:06.000000000 +0200
@@ -0,0 +1,7 @@
+/* Test for computed jump into cond_expr: bug 17913.  */
+void f (void) 
+{ 
+  void *p = &&a;
+  1 ? 1 : ({ a : 1; }); 
+  goto *p;
+}


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