This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch for bugs 772 and 17913
- From: Gábor Lóki <loki at inf dot u-szeged dot hu>
- To: Roger Sayle <roger at eyesopen dot com>
- Cc: Mark Mitchell <mark at codesourcery dot com>,"Joseph S. Myers" <joseph at codesourcery dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 03 May 2005 13:47:24 +0200
- Subject: Re: Patch for bugs 772 and 17913
- References: <Pine.LNX.4.44.0505021017240.10470-100000@www.eyesopen.com>
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;
+}