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


Mark Mitchell wrote:
Joseph S. Myers wrote:

This patch addresses bugs 772 and 17913 by disallowing jumps into
statement expressions for C.

The langhooks part of Gabor's patch is fine. Given Roger's comment that he's happy with the middle-end changes, the patch is OK for 4.0 and mainline, modulo Joseph's comments about formatting, etc. Gabor, would you please revise accordingly?

Sorry for the late answer, but I haven't got enough time for GCC in the last month.

I have checked my patch against mainline and found that the langhook
isn't necessary. Because I only used langhooks to check
CASE_LABEL_EXPR, and now the '(/*no switch*/{ ... case xxx: ... })'
code is not allowed. So I think that no need for this langhook.
Did I miss anything?

So, I have removed the langhooks and rewritten the tree walking
functions.

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

br,
   Gabor Loki

---

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

	PR c/17913
	* c-types.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.438
diff -u -r1.438 c-typeck.c
--- gcc/gcc/c-typeck.c	28 Apr 2005 00:45:42 -0000	1.438
+++ gcc/gcc/c-typeck.c	2 May 2005 12:00:42 -0000
@@ -3088,9 +3088,6 @@
   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));
 }
 
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	2 May 2005 12:00:42 -0000
@@ -134,6 +134,8 @@
 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 tree contains_label_1 (tree*, int*, void*);
+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 +9949,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 +11598,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 13:36:58.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]