PR c++/68767
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Jan 2016 15:54:14 +0000 (15:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Jan 2016 15:54:14 +0000 (15:54 +0000)
gcc/c-family/
* c-common.c (check_function_arguments_recurse): Fold the whole
COND_EXPR, not just the condition.
gcc/cp/
* cp-gimplify.c (cp_fold) [COND_EXPR]: Simplify.  Do fold COND_EXPR.
(contains_label_1, contains_label_p): Remove.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232522 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/testsuite/g++.dg/warn/Wnonnull2.C [new file with mode: 0644]

index 33f2884..a22485f 100644 (file)
@@ -1,3 +1,9 @@
+2016-01-18  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68767
+       * c-common.c (check_function_arguments_recurse): Fold the whole
+       COND_EXPR, not just the condition.
+
 2016-01-18  Tom de Vries  <tom@codesourcery.com>
 
        * c-omp.c (c_oacc_split_loop_clauses): Don't copy OMP_CLAUSE_REDUCTION,
index 0bfa1f6..1a2c21b 100644 (file)
@@ -9765,15 +9765,19 @@ check_function_arguments_recurse (void (*callback)
 
   if (TREE_CODE (param) == COND_EXPR)
     {
-      tree cond = fold_for_warn (TREE_OPERAND (param, 0));
-      /* Check both halves of the conditional expression.  */
-      if (!integer_zerop (cond))
-       check_function_arguments_recurse (callback, ctx,
-                                         TREE_OPERAND (param, 1), param_num);
-      if (!integer_nonzerop (cond))
-       check_function_arguments_recurse (callback, ctx,
-                                         TREE_OPERAND (param, 2), param_num);
-      return;
+      /* Simplify to avoid warning for an impossible case.  */
+      param = fold_for_warn (param);
+      if (TREE_CODE (param) == COND_EXPR)
+       {
+         /* Check both halves of the conditional expression.  */
+         check_function_arguments_recurse (callback, ctx,
+                                           TREE_OPERAND (param, 1),
+                                           param_num);
+         check_function_arguments_recurse (callback, ctx,
+                                           TREE_OPERAND (param, 2),
+                                           param_num);
+         return;
+       }
     }
 
   (*callback) (ctx, param, param_num);
index 6b7e81b..0ae2912 100644 (file)
@@ -1,3 +1,9 @@
+2016-01-18  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68767
+       * cp-gimplify.c (cp_fold) [COND_EXPR]: Simplify.  Do fold COND_EXPR.
+       (contains_label_1, contains_label_p): Remove.
+
 2016-01-16  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/69091
index c0ee8e4..e151753 100644 (file)
@@ -1851,38 +1851,6 @@ cxx_omp_disregard_value_expr (tree decl, bool shared)
         && DECL_OMP_PRIVATIZED_MEMBER (decl);
 }
 
-/* Callback for walk_tree, looking for LABEL_EXPR.  Return *TP if it is
-   a LABEL_EXPR; otherwise return NULL_TREE.  Do not check the subtrees
-   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;
-
-      /* ... fall through ...  */
-
-    default:
-      return NULL_TREE;
-    }
-}
-
-/* Return whether the sub-tree ST contains a label which is accessible from
-   outside the sub-tree.  */
-
-static bool
-contains_label_p (tree st)
-{
-  return
-   walk_tree_without_duplicates (&st, contains_label_1 , NULL) != NULL_TREE;
-}
-
 /* Perform folding on expression X.  */
 
 tree
@@ -2110,54 +2078,22 @@ cp_fold (tree x)
     case VEC_COND_EXPR:
     case COND_EXPR:
 
+      /* Don't bother folding a void condition, since it can't produce a
+        constant value.  Also, some statement-level uses of COND_EXPR leave
+        one of the branches NULL, so folding would crash.  */
+      if (VOID_TYPE_P (TREE_TYPE (x)))
+       return x;
+
       loc = EXPR_LOCATION (x);
       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
-
-      if (TREE_SIDE_EFFECTS (op0))
-       break;
-
       op1 = cp_fold (TREE_OPERAND (x, 1));
       op2 = cp_fold (TREE_OPERAND (x, 2));
 
-      if (TREE_CODE (op0) == INTEGER_CST)
-       {
-         tree un;
-
-         if (integer_zerop (op0))
-           {
-             un = op1;
-             r = op2;
-           }
-         else
-           {
-             un = op2;
-             r = op1;
-           }
-
-          if ((!TREE_SIDE_EFFECTS (un) || !contains_label_p (un))
-              && (! VOID_TYPE_P (TREE_TYPE (r)) || VOID_TYPE_P (x)))
-            {
-             if (CAN_HAVE_LOCATION_P (r)
-                 && EXPR_LOCATION (r) != loc
-                 && !(TREE_CODE (r) == SAVE_EXPR
-                      || TREE_CODE (r) == TARGET_EXPR
-                      || TREE_CODE (r) == BIND_EXPR))
-               {
-                 r = copy_node (r);
-                 SET_EXPR_LOCATION (r, loc);
-               }
-             x = r;
-           }
-
-         break;
-       }
-
-      if (VOID_TYPE_P (TREE_TYPE (x)))
-       break;
-
-      x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
-
-      if (code != COND_EXPR)
+      if (op0 != TREE_OPERAND (x, 0)
+         || op1 != TREE_OPERAND (x, 1)
+         || op2 != TREE_OPERAND (x, 2))
+       x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
+      else
        x = fold (x);
 
       break;
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull2.C b/gcc/testsuite/g++.dg/warn/Wnonnull2.C
new file mode 100644 (file)
index 0000000..6757437
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/68767
+// { dg-options "-Wnonnull" }
+
+extern int len (const char*) __attribute__ ((__nonnull__ (1)));
+
+int f (int x)
+{
+  return len ((x ? "x" : 0) ? (x ? "x" : 0) : "x");
+}