aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabor Loki <loki@gcc.gnu.org>2005-05-10 13:47:05 +0000
committerGabor Loki <loki@gcc.gnu.org>2005-05-10 13:47:05 +0000
commitce380b0bead7139af75af190176aaacf4f76a6ec (patch)
tree6381aa5b39ee6d67c9cf69d7ebad4dae77e66a24
parentba8fc1150ef54cd4868aadcb659d9032d9c6e288 (diff)
2005-05-10 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-10 Gabor Loki <loki@gcc.gnu.org> PR c/17913 * gcc.c-torture/compile/pr17913.c: Computed jump test for PR17913 git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@99514 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-typeck.c5
-rw-r--r--gcc/fold-const.c41
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr17913.c7
5 files changed, 59 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ffdd2bbff2a..ab0ce03d03f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-05-10 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.
+
2005-05-10 Joseph S. Myers <joseph@codesourcery.com>
PR c/21342
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index d3b1c957020..806a20ade96 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -3105,10 +3105,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 140f940af27..0f3c8dd29e7 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9905,6 +9905,37 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
} /* switch (code) */
}
+/* 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);
+}
+
/* Fold a ternary expression of code CODE and type TYPE with operands
OP0, OP1, and OP2. Return the folded expression if folding is
successful. Otherwise, return NULL_TREE. */
@@ -9958,12 +9989,16 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7dd2e1970d9..6b8ce931eb3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-05-10 Gabor Loki <loki@gcc.gnu.org>
+
+ PR c/17913
+ * gcc.c-torture/compile/pr17913.c: Computed jump test for PR17913
+
2005-05-10 Joseph S. Myers <joseph@codesourcery.com>
PR c/21342
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr17913.c b/gcc/testsuite/gcc.c-torture/compile/pr17913.c
new file mode 100644
index 00000000000..30654a395d6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr17913.c
@@ -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;
+}