OSDN Git Service

2005-05-10 Gabor Loki <loki@gcc.gnu.org>
authorloki <loki@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 May 2005 13:47:05 +0000 (13:47 +0000)
committerloki <loki@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 May 2005 13:47:05 +0000 (13:47 +0000)
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99514 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr17913.c [new file with mode: 0644]

index ffdd2bb..ab0ce03 100644 (file)
@@ -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
 2005-05-10  Joseph S. Myers  <joseph@codesourcery.com>
 
        PR c/21342
index d3b1c95..806a20a 100644 (file)
@@ -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 (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);
 }
 \f
 /* Return a compound expression that performs two expressions and
 }
 \f
 /* Return a compound expression that performs two expressions and
index 140f940..0f3c8dd 100644 (file)
@@ -9905,6 +9905,37 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
     } /* switch (code) */
 }
 
     } /* 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.  */
 /* 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)
        {
         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
          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;
        }
            return pedantic_non_lvalue (tem);
          return NULL_TREE;
        }
index 7dd2e19..6b8ce93 100644 (file)
@@ -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
 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 (file)
index 0000000..30654a3
--- /dev/null
@@ -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;
+}