OSDN Git Service

2008-10-24 Manuel López-Ibáñez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 2008 10:09:06 +0000 (10:09 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 2008 10:09:06 +0000 (10:09 +0000)
PR c/7543
* value-prof.c (gimple_stringop_fixed_value): Use parentheses
around bit operation.
* profile.c (is_edge_inconsistent): Likewise.
* fold-const.c (truth_value_p): Move from here...
* tree.h (truth_value_p): ... to here.
* c-tree.h (c_expr): Update description of original_code.
* c-typeck.c (parser_build_unary_op): Set original_code.
(parser_build_binary_op): Update call to warn_about_parentheses.
* c-common.c (warn_about_parentheses): Take two additional
arguments of the operands. Use a switch. Quote operators
appropriately. Define macro APPEARS_TO_BE_BOOLEAN_EXPR_P.
Add warning about !x | y and !x & y.
* c-common.h (warn_about_parentheses): Update declaration.
cp/
* typeck.c (build_x_binary_op): Update call to
warn_about_parentheses.
* parser.c (cp_parser_binary_expression): Add note about passing
the correct code for unary expressions.
testsuite/
* gcc.dg/Wparentheses-11.c: New.
* g++.dg/warn/Wparentheses-25.C: New. XFAILED.

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

15 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-tree.h
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/typeck.c
gcc/fold-const.c
gcc/profile.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wparentheses-25.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wparentheses-11.c [new file with mode: 0644]
gcc/tree.h
gcc/value-prof.c

index 840e0eb..18b0e80 100644 (file)
@@ -1,3 +1,20 @@
+2008-10-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/7543
+       * value-prof.c (gimple_stringop_fixed_value): Use parentheses
+       around bit operation.
+       * profile.c (is_edge_inconsistent): Likewise.
+       * fold-const.c (truth_value_p): Move from here...
+       * tree.h (truth_value_p): ... to here.
+       * c-tree.h (c_expr): Update description of original_code.
+       * c-typeck.c (parser_build_unary_op): Set original_code.
+       (parser_build_binary_op): Update call to warn_about_parentheses.
+       * c-common.c (warn_about_parentheses): Take two additional
+       arguments of the operands. Use a switch. Quote operators
+       appropriately. Define macro APPEARS_TO_BE_BOOLEAN_EXPR_P.
+       Add warning about !x | y and !x & y.
+       * c-common.h (warn_about_parentheses): Update declaration.
+
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile.in (lang_checks_parallelized, check_gcc_parallelize,
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile.in (lang_checks_parallelized, check_gcc_parallelize,
index 6b37c34..30acb7d 100644 (file)
@@ -8076,94 +8076,132 @@ warn_array_subscript_with_type_char (tree index)
 /* Implement -Wparentheses for the unexpected C precedence rules, to
    cover cases like x + y << z which readers are likely to
    misinterpret.  We have seen an expression in which CODE is a binary
 /* Implement -Wparentheses for the unexpected C precedence rules, to
    cover cases like x + y << z which readers are likely to
    misinterpret.  We have seen an expression in which CODE is a binary
-   operator used to combine expressions headed by CODE_LEFT and
-   CODE_RIGHT.  CODE_LEFT and CODE_RIGHT may be ERROR_MARK, which
-   means that that side of the expression was not formed using a
-   binary operator, or it was enclosed in parentheses.  */
+   operator used to combine expressions ARG_LEFT and ARG_RIGHT, which
+   before folding had CODE_LEFT and CODE_RIGHT.  CODE_LEFT and
+   CODE_RIGHT may be ERROR_MARK, which means that that side of the
+   expression was not formed using a binary or unary operator, or it
+   was enclosed in parentheses.  */
 
 void
 
 void
-warn_about_parentheses (enum tree_code code, enum tree_code code_left,
-                       enum tree_code code_right)
+warn_about_parentheses (enum tree_code code,
+                       enum tree_code code_left, tree ARG_UNUSED (arg_left),
+                       enum tree_code code_right, tree arg_right)
 {
   if (!warn_parentheses)
     return;
 
 {
   if (!warn_parentheses)
     return;
 
-  if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
+  /* This macro tests that the expression ARG with original tree code
+     CODE appears to be a boolean expression. or the result of folding a
+     boolean expression.  */
+#define APPEARS_TO_BE_BOOLEAN_EXPR_P(CODE, ARG)                             \
+       (truth_value_p (TREE_CODE (ARG))                                    \
+        || TREE_CODE (TREE_TYPE (ARG)) == BOOLEAN_TYPE                     \
+        /* Folding may create 0 or 1 integers from other expressions.  */  \
+        || ((CODE) != INTEGER_CST                                          \
+            && (integer_onep (ARG) || integer_zerop (ARG))))
+
+  switch (code) 
     {
     {
-      if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
-         || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+    case LSHIFT_EXPR:
+      if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around + or - inside shift");
-    }
+                "suggest parentheses around %<+%> inside %<<<%>");
+      else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
+       warning (OPT_Wparentheses,
+                "suggest parentheses around %<-%> inside %<<<%>");
+      return;
 
 
-  if (code == TRUTH_ORIF_EXPR)
-    {
-      if (code_left == TRUTH_ANDIF_EXPR
-         || code_right == TRUTH_ANDIF_EXPR)
+    case RSHIFT_EXPR:
+      if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around && within ||");
-    }
+                "suggest parentheses around %<+%> inside %<>>%>");
+      else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
+       warning (OPT_Wparentheses,
+                "suggest parentheses around %<-%> inside %<>>%>");
+      return;
 
 
-  if (code == BIT_IOR_EXPR)
-    {
+    case TRUTH_ORIF_EXPR:
+      if (code_left == TRUTH_ANDIF_EXPR || code_right == TRUTH_ANDIF_EXPR)
+       warning (OPT_Wparentheses,
+                "suggest parentheses around %<&&%> within %<||%>");
+      return;
+
+    case BIT_IOR_EXPR:
       if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
          || code_left == PLUS_EXPR || code_left == MINUS_EXPR
          || code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
          || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
        warning (OPT_Wparentheses,
       if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
          || code_left == PLUS_EXPR || code_left == MINUS_EXPR
          || code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
          || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
        warning (OPT_Wparentheses,
-                "suggest parentheses around arithmetic in operand of |");
+                "suggest parentheses around arithmetic in operand of %<|%>");
       /* Check cases like x|y==z */
       /* Check cases like x|y==z */
-      if (TREE_CODE_CLASS (code_left) == tcc_comparison
-         || TREE_CODE_CLASS (code_right) == tcc_comparison)
+      else if (TREE_CODE_CLASS (code_left) == tcc_comparison
+              || TREE_CODE_CLASS (code_right) == tcc_comparison)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around comparison in operand of |");
-    }
+                "suggest parentheses around comparison in operand of %<|%>");
+      /* Check cases like !x | y */
+      else if (code_left == TRUTH_NOT_EXPR
+              && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
+       warning (OPT_Wparentheses, "suggest parentheses around operand of"
+                "%<!%> or change %<|%> to %<||%> or %<!%> to %<~%>");
+      return;
 
 
-  if (code == BIT_XOR_EXPR)
-    {
+    case BIT_XOR_EXPR:
       if (code_left == BIT_AND_EXPR
          || code_left == PLUS_EXPR || code_left == MINUS_EXPR
          || code_right == BIT_AND_EXPR
          || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
        warning (OPT_Wparentheses,
       if (code_left == BIT_AND_EXPR
          || code_left == PLUS_EXPR || code_left == MINUS_EXPR
          || code_right == BIT_AND_EXPR
          || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
        warning (OPT_Wparentheses,
-                "suggest parentheses around arithmetic in operand of ^");
+                "suggest parentheses around arithmetic in operand of %<^%>");
       /* Check cases like x^y==z */
       /* Check cases like x^y==z */
-      if (TREE_CODE_CLASS (code_left) == tcc_comparison
-         || TREE_CODE_CLASS (code_right) == tcc_comparison)
+      else if (TREE_CODE_CLASS (code_left) == tcc_comparison
+              || TREE_CODE_CLASS (code_right) == tcc_comparison)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around comparison in operand of ^");
-    }
+                "suggest parentheses around comparison in operand of %<^%>");
+      return;
 
 
-  if (code == BIT_AND_EXPR)
-    {
-      if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
-         || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+    case BIT_AND_EXPR:
+      if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
+       warning (OPT_Wparentheses,
+                "suggest parentheses around %<+%> in operand of %<&%>");
+      else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around + or - in operand of &");
+                "suggest parentheses around %<-%> in operand of %<&%>");
       /* Check cases like x&y==z */
       /* Check cases like x&y==z */
-      if (TREE_CODE_CLASS (code_left) == tcc_comparison
-         || TREE_CODE_CLASS (code_right) == tcc_comparison)
+      else if (TREE_CODE_CLASS (code_left) == tcc_comparison
+              || TREE_CODE_CLASS (code_right) == tcc_comparison)
        warning (OPT_Wparentheses,
        warning (OPT_Wparentheses,
-                "suggest parentheses around comparison in operand of &");
-    }
+                "suggest parentheses around comparison in operand of %<&%>");
+      /* Check cases like !x & y */
+      else if (code_left == TRUTH_NOT_EXPR
+              && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
+       warning (OPT_Wparentheses, "suggest parentheses around operand of"
+                "%<!%> or change %<&%> to %<&&%> or %<!%> to %<~%>");
+      return;
 
 
-  if (code == EQ_EXPR || code == NE_EXPR)
-    {
+    case EQ_EXPR:
       if (TREE_CODE_CLASS (code_left) == tcc_comparison
           || TREE_CODE_CLASS (code_right) == tcc_comparison)
        warning (OPT_Wparentheses,
       if (TREE_CODE_CLASS (code_left) == tcc_comparison
           || TREE_CODE_CLASS (code_right) == tcc_comparison)
        warning (OPT_Wparentheses,
-                "suggest parentheses around comparison in operand of %s",
-                 code == EQ_EXPR ? "==" : "!=");
-    }
-  else if (TREE_CODE_CLASS (code) == tcc_comparison)
-    {
-      if ((TREE_CODE_CLASS (code_left) == tcc_comparison
-          && code_left != NE_EXPR && code_left != EQ_EXPR)
-         || (TREE_CODE_CLASS (code_right) == tcc_comparison
-             && code_right != NE_EXPR && code_right != EQ_EXPR))
-       warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
+                "suggest parentheses around comparison in operand of %<==%>");
+      return;
+    case NE_EXPR:
+      if (TREE_CODE_CLASS (code_left) == tcc_comparison
+          || TREE_CODE_CLASS (code_right) == tcc_comparison)
+       warning (OPT_Wparentheses,
+                "suggest parentheses around comparison in operand of %<!=%>");
+      return;
+
+    default:
+      if (TREE_CODE_CLASS (code) == tcc_comparison
+          && ((TREE_CODE_CLASS (code_left) == tcc_comparison
+               && code_left != NE_EXPR && code_left != EQ_EXPR)
+              || (TREE_CODE_CLASS (code_right) == tcc_comparison
+                  && code_right != NE_EXPR && code_right != EQ_EXPR)))
+       warning (OPT_Wparentheses, "comparisons like %<X<=Y<=Z%> do not "
                 "have their mathematical meaning");
                 "have their mathematical meaning");
+      return;
     }
     }
+#undef NOT_A_BOOLEAN_EXPR_P
 }
 
 /* If LABEL (a LABEL_DECL) has not been used, issue a warning.  */
 }
 
 /* If LABEL (a LABEL_DECL) has not been used, issue a warning.  */
index cd4eb31..be38a60 100644 (file)
@@ -912,8 +912,9 @@ extern int complete_array_type (tree *, tree, bool);
 extern tree builtin_type_for_size (int, bool);
 
 extern void warn_array_subscript_with_type_char (tree);
 extern tree builtin_type_for_size (int, bool);
 
 extern void warn_array_subscript_with_type_char (tree);
-extern void warn_about_parentheses (enum tree_code, enum tree_code,
-                                   enum tree_code);
+extern void warn_about_parentheses (enum tree_code,
+                                   enum tree_code, tree,
+                                   enum tree_code, tree);
 extern void warn_for_unused_label (tree label);
 extern void warn_for_div_by_zero (location_t, tree divisor);
 extern void warn_for_sign_compare (location_t,
 extern void warn_for_unused_label (tree label);
 extern void warn_for_div_by_zero (location_t, tree divisor);
 extern void warn_for_sign_compare (location_t,
index 26ef664..b7430af 100644 (file)
@@ -151,7 +151,7 @@ struct c_expr
 {
   /* The value of the expression.  */
   tree value;
 {
   /* The value of the expression.  */
   tree value;
-  /* Record the original binary operator of an expression, which may
+  /* Record the original unary/binary operator of an expression, which may
      have been changed by fold, STRING_CST for unparenthesized string
      constants, or ERROR_MARK for other expressions (including
      parenthesized expressions).  */
      have been changed by fold, STRING_CST for unparenthesized string
      constants, or ERROR_MARK for other expressions (including
      parenthesized expressions).  */
index 52042fa..27564e6 100644 (file)
@@ -2748,9 +2748,9 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
 {
   struct c_expr result;
 
 {
   struct c_expr result;
 
-  result.original_code = ERROR_MARK;
   result.value = build_unary_op (loc, code, arg.value, 0);
   result.value = build_unary_op (loc, code, arg.value, 0);
-
+  result.original_code = code;
+  
   if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
     overflow_warning (result.value);
 
   if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
     overflow_warning (result.value);
 
@@ -2787,7 +2787,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
   /* Check for cases such as x+y<<z which users are likely
      to misinterpret.  */
   if (warn_parentheses)
   /* Check for cases such as x+y<<z which users are likely
      to misinterpret.  */
   if (warn_parentheses)
-    warn_about_parentheses (code, code1, code2);
+    warn_about_parentheses (code, code1, arg1.value, code2, arg2.value);
 
   if (TREE_CODE_CLASS (code1) != tcc_comparison)
     warn_logical_operator (code, arg1.value, arg2.value);
 
   if (TREE_CODE_CLASS (code1) != tcc_comparison)
     warn_logical_operator (code, arg1.value, arg2.value);
index ee09f15..0293d49 100644 (file)
@@ -1,3 +1,11 @@
+2008-10-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/7543
+       * typeck.c (build_x_binary_op): Update call to
+       warn_about_parentheses.
+       * parser.c (cp_parser_binary_expression): Add note about passing
+       the correct code for unary expressions.
+
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        * Make-lang.in (check-c++-subtargets): New alias for
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        * Make-lang.in (check-c++-subtargets): New alias for
index 519c1d6..7596048 100644 (file)
@@ -6205,6 +6205,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
        }
 
       overloaded_p = false;
        }
 
       overloaded_p = false;
+      /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
+        ERROR_MARK for everything that is not a binary expression.
+        This makes warn_about_parentheses miss some warnings that
+        involve unary operators.  For unary expressions we should
+        pass the correct tree_code unless the unary expression was
+        surrounded by parentheses.
+      */
       lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
                               &overloaded_p, tf_warning_or_error);
       lhs_type = tree_type;
       lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
                               &overloaded_p, tf_warning_or_error);
       lhs_type = tree_type;
index 9e65bdd..84ebc95 100644 (file)
@@ -3158,7 +3158,7 @@ build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
       && !error_operand_p (arg2)
       && (code != LSHIFT_EXPR
          || !CLASS_TYPE_P (TREE_TYPE (arg1))))
       && !error_operand_p (arg2)
       && (code != LSHIFT_EXPR
          || !CLASS_TYPE_P (TREE_TYPE (arg1))))
-    warn_about_parentheses (code, arg1_code, arg2_code);
+    warn_about_parentheses (code, arg1_code, orig_arg1, arg2_code, orig_arg2);
 
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
 
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
index 88e70d6..1eac946 100644 (file)
@@ -105,7 +105,6 @@ static enum comparison_code comparison_to_compcode (enum tree_code);
 static enum tree_code compcode_to_comparison (enum comparison_code);
 static tree combine_comparisons (enum tree_code, enum tree_code,
                                 enum tree_code, tree, tree, tree);
 static enum tree_code compcode_to_comparison (enum comparison_code);
 static tree combine_comparisons (enum tree_code, enum tree_code,
                                 enum tree_code, tree, tree, tree);
-static int truth_value_p (enum tree_code);
 static int operand_equal_for_comparison_p (tree, tree, tree);
 static int twoval_comparison_p (tree, tree *, tree *, int *);
 static tree eval_subst (tree, tree, tree, tree, tree);
 static int operand_equal_for_comparison_p (tree, tree, tree);
 static int twoval_comparison_p (tree, tree *, tree *, int *);
 static tree eval_subst (tree, tree, tree, tree, tree);
@@ -2981,17 +2980,6 @@ combine_comparisons (enum tree_code code, enum tree_code lcode,
     return fold_build2 (compcode_to_comparison (compcode),
                        truth_type, ll_arg, lr_arg);
 }
     return fold_build2 (compcode_to_comparison (compcode),
                        truth_type, ll_arg, lr_arg);
 }
-
-/* Return nonzero if CODE is a tree code that represents a truth value.  */
-
-static int
-truth_value_p (enum tree_code code)
-{
-  return (TREE_CODE_CLASS (code) == tcc_comparison
-         || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
-         || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
-         || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
-}
 \f
 /* Return nonzero if two operands (typically of the same tree node)
    are necessarily equal.  If either argument has side-effects this
 \f
 /* Return nonzero if two operands (typically of the same tree node)
    are necessarily equal.  If either argument has side-effects this
index 976d91c..c4c7276 100644 (file)
@@ -278,7 +278,7 @@ is_edge_inconsistent (VEC(edge,gc) *edges)
       if (!EDGE_INFO (e)->ignore)
         {
           if (e->count < 0
       if (!EDGE_INFO (e)->ignore)
         {
           if (e->count < 0
-             && ((!e->flags & EDGE_FAKE)
+             && (!(e->flags & EDGE_FAKE)
                  || !block_ends_with_call_p (e->src)))
            {
              if (dump_file)
                  || !block_ends_with_call_p (e->src)))
            {
              if (dump_file)
index 29fe92c..bf56e53 100644 (file)
@@ -1,3 +1,9 @@
+2008-10-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/7543
+       * gcc.dg/Wparentheses-11.c: New.
+       * g++.dg/warn/Wparentheses-25.C: New. XFAILED.
+
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/37882
 2008-10-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/37882
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-25.C b/gcc/testsuite/g++.dg/warn/Wparentheses-25.C
new file mode 100644 (file)
index 0000000..ab00c25
--- /dev/null
@@ -0,0 +1,259 @@
+/* PR 7543. Test operation of -Wparentheses.  Precedence warnings.  
+   !a | b and !a & b. */
+/* { dg-do compile } */
+/* { dg-options "-Wparentheses" } */
+// C++ version of Wparentheses-11.c
+int foo (int);
+
+int
+bar (int a, int b, int c)
+{
+  foo (!a & b); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b < c));
+  foo (!a & (b > c));
+  foo (!a & (b == c));
+  foo (!a & (b != c));
+  foo (!a & (b <= c));
+  foo (!a & (b >= c));
+  foo (!a & (b && c));
+  foo (!a & (b || c));
+  foo (!a & !b);
+  foo (!(a & b));
+  foo ((!a) & b);
+  foo (!a & 2); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 < c));
+  foo (!a & (2 > c));
+  foo (!a & (2 == c));
+  foo (!a & (2 != c));
+  foo (!a & (2 <= c));
+  foo (!a & (2 >= c));
+  foo (!a & (2 && c));
+  foo (!a & (2 || c));
+  foo (!a & !2);
+  foo (!(a & 2));
+  foo ((!a) & 2);
+  foo (!1 & 2); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 < c));
+  foo (!1 & (2 > c));
+  foo (!1 & (2 == c));
+  foo (!1 & (2 != c));
+  foo (!1 & (2 <= c));
+  foo (!1 & (2 >= c));
+  foo (!1 & (2 && c));
+  foo (!1 & (2 || c));
+  foo (!1 & !2);
+  foo (!(1 & 2));
+
+  foo (!a | b); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b < c));
+  foo (!a | (b > c));
+  foo (!a | (b == c));
+  foo (!a | (b != c));
+  foo (!a | (b <= c));
+  foo (!a | (b >= c));
+  foo (!a | (b && c));
+  foo (!a | (b || c));
+  foo (!a | !b);
+  foo (!(a | b));
+  foo ((!a) | b);
+  foo (!a | 2); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 < c));
+  foo (!a | (2 > c));
+  foo (!a | (2 == c));
+  foo (!a | (2 != c));
+  foo (!a | (2 <= c));
+  foo (!a | (2 >= c));
+  foo (!a | (2 && c));
+  foo (!a | (2 || c));
+  foo (!a | !2);
+  foo (!(a | 2));
+  foo ((!a) | 2);
+  foo (!1 | 2); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 < c));
+  foo (!1 | (2 > c));
+  foo (!1 | (2 == c));
+  foo (!1 | (2 != c));
+  foo (!1 | (2 <= c));
+  foo (!1 | (2 >= c));
+  foo (!1 | (2 && c));
+  foo (!1 | (2 || c));
+  foo (!1 | !2);
+  foo (!(1 | 2));
+  foo ((!1) | 2);
+
+  foo (b & !a); /* { dg-bogus "parentheses" "bogus warning" } */
+  foo ((b < c) & !a);
+  foo ((b > c) & !a);
+  foo ((b == c) & !a);
+  foo ((b != c) & !a);
+  foo ((b <= c) & !a);
+  foo ((b >= c) & !a);
+  foo ((b && c) & !a);
+  foo ((b || c) & !a);
+  foo (!b & !a);
+  foo (!(b & a));
+  foo (b & (!a));
+  foo (2 & !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) & !a);
+  foo ((2 > c) & !a);
+  foo ((2 == c) & !a);
+  foo ((2 != c) & !a);
+  foo ((2 <= c) & !a);
+  foo ((2 >= c) & !a);
+  foo ((2 && c) & !a);
+  foo ((2 || c) & !a);
+  foo (!2 & !a);
+  foo (!(2 & a));
+  foo (2 & (!a));
+  foo (2 & !1); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) & !1);
+  foo ((2 > c) & !1);
+  foo ((2 == c) & !1);
+  foo ((2 != c) & !1);
+  foo ((2 <= c) & !1);
+  foo ((2 >= c) & !1);
+  foo ((2 && c) & !1);
+  foo ((2 || c) & !1);
+  foo (!2 & !1);
+  foo (!(2 & 1));
+
+  foo (b | !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((b < c) | !a);
+  foo ((b > c) | !a);
+  foo ((b == c) | !a);
+  foo ((b != c) | !a);
+  foo ((b <= c) | !a);
+  foo ((b >= c) | !a);
+  foo ((b && c) | !a);
+  foo ((b || c) | !a);
+  foo (!b | !a);
+  foo (!(b | a));
+  foo (b | (!a));
+  foo (2 | !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) | !a);
+  foo ((2 > c) | !a);
+  foo ((2 == c) | !a);
+  foo ((2 != c) | !a);
+  foo ((2 <= c) | !a);
+  foo ((2 >= c) | !a);
+  foo ((2 && c) | !a);
+  foo ((2 || c) | !a);
+  foo (!2 | !a);
+  foo (!(2 | a));
+  foo (2 | (!a));
+  foo (2 | !1); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) | !1);
+  foo ((2 > c) | !1);
+  foo ((2 == c) | !1);
+  foo ((2 != c) | !1);
+  foo ((2 <= c) | !1);
+  foo ((2 >= c) | !1);
+  foo ((2 && c) | !1);
+  foo ((2 || c) | !1);
+  foo (!2 | !1);
+  foo (!(2 | 1));
+  foo (2 | (!1));
+}
+
+
+int
+baz (int a, int b, int c)
+{
+  foo (!a & (b << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b = c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & ~b);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (b | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & 2);       /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (c = 2)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & ~2);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a & (2 | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (c = 2)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & ~2);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 & (2 | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b = c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | ~b);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (b | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (c = 2)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | ~2);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!a | (2 | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 << c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 >> c));/* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 + c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 - c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (c = 2)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | ~2);      /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 & c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo (!1 | (2 | c)); /* { dg-warning "parentheses" "correct warning" { xfail *-*-* } } */
+  foo ((b << c) & !a);
+  foo ((b >> c) & !a);
+  foo ((b + c) & !a);
+  foo ((b - c) & !a);
+  foo ((b = c) & !a);
+  foo (~b & !a);
+  foo ((b & c) & !a);
+  foo ((b | c) & !a);
+  foo ((2 << c) & !a);
+  foo ((2 >> c) & !a);
+  foo ((2 + c) & !a);
+  foo ((2 - c) & !a);
+  foo ((c = 2) & !a);
+  foo (~2 & !a);
+  foo ((2 & c) & !a);
+  foo ((2 | c) & !a);
+  foo ((2 << c) & !1);
+  foo ((2 >> c) & !1);
+  foo ((2 + c) & !1);
+  foo ((2 - c) & !1);
+  foo ((c = 2) & !1);
+  foo (~2 & !1);
+  foo ((2 & c) & !1);
+  foo ((2 | c) & !1);
+  foo ((b << c) | !a);
+  foo ((b >> c) | !a);
+  foo ((b + c) | !a);
+  foo ((b - c) | !a);
+  foo ((b = c) | !a);
+  foo (~b | !a);
+  foo ((b & c) | !a);
+  foo ((b | c) | !a);
+  foo ((2 << c) | !a);
+  foo ((2 >> c) | !a);
+  foo ((2 + c) | !a);
+  foo ((2 - c) | !a);
+  foo ((c = 2) | !a);
+  foo (~2 | !a);
+  foo ((2 & c) | !a);
+  foo ((2 | c) | !a);
+  foo ((2 << c) | !1);
+  foo ((2 >> c) | !1);
+  foo ((2 + c) | !1);
+  foo ((2 - c) | !1);
+  foo ((c = 2) | !1);
+  foo (~2 | !1);
+  foo ((2 & c) | !1);
+  foo ((2 | c) | !1);
+}
diff --git a/gcc/testsuite/gcc.dg/Wparentheses-11.c b/gcc/testsuite/gcc.dg/Wparentheses-11.c
new file mode 100644 (file)
index 0000000..8858a7f
--- /dev/null
@@ -0,0 +1,258 @@
+/* PR 7543. Test operation of -Wparentheses.  Precedence warnings.  
+   !a | b and !a & b. */
+/* { dg-do compile } */
+/* { dg-options "-Wparentheses" } */
+
+int foo (int);
+
+int
+bar (int a, int b, int c)
+{
+  foo (!a & b); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b < c));
+  foo (!a & (b > c));
+  foo (!a & (b == c));
+  foo (!a & (b != c));
+  foo (!a & (b <= c));
+  foo (!a & (b >= c));
+  foo (!a & (b && c));
+  foo (!a & (b || c));
+  foo (!a & !b);
+  foo (!(a & b));
+  foo ((!a) & b);
+  foo (!a & 2); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 < c));
+  foo (!a & (2 > c));
+  foo (!a & (2 == c));
+  foo (!a & (2 != c));
+  foo (!a & (2 <= c));
+  foo (!a & (2 >= c));
+  foo (!a & (2 && c));
+  foo (!a & (2 || c));
+  foo (!a & !2);
+  foo (!(a & 2));
+  foo ((!a) & 2);
+  foo (!1 & 2); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 < c));
+  foo (!1 & (2 > c));
+  foo (!1 & (2 == c));
+  foo (!1 & (2 != c));
+  foo (!1 & (2 <= c));
+  foo (!1 & (2 >= c));
+  foo (!1 & (2 && c));
+  foo (!1 & (2 || c));
+  foo (!1 & !2);
+  foo (!(1 & 2));
+
+  foo (!a | b); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b < c));
+  foo (!a | (b > c));
+  foo (!a | (b == c));
+  foo (!a | (b != c));
+  foo (!a | (b <= c));
+  foo (!a | (b >= c));
+  foo (!a | (b && c));
+  foo (!a | (b || c));
+  foo (!a | !b);
+  foo (!(a | b));
+  foo ((!a) | b);
+  foo (!a | 2); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 < c));
+  foo (!a | (2 > c));
+  foo (!a | (2 == c));
+  foo (!a | (2 != c));
+  foo (!a | (2 <= c));
+  foo (!a | (2 >= c));
+  foo (!a | (2 && c));
+  foo (!a | (2 || c));
+  foo (!a | !2);
+  foo (!(a | 2));
+  foo ((!a) | 2);
+  foo (!1 | 2); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 < c));
+  foo (!1 | (2 > c));
+  foo (!1 | (2 == c));
+  foo (!1 | (2 != c));
+  foo (!1 | (2 <= c));
+  foo (!1 | (2 >= c));
+  foo (!1 | (2 && c));
+  foo (!1 | (2 || c));
+  foo (!1 | !2);
+  foo (!(1 | 2));
+  foo ((!1) | 2);
+
+  foo (b & !a); /* { dg-bogus "parentheses" "bogus warning" } */
+  foo ((b < c) & !a);
+  foo ((b > c) & !a);
+  foo ((b == c) & !a);
+  foo ((b != c) & !a);
+  foo ((b <= c) & !a);
+  foo ((b >= c) & !a);
+  foo ((b && c) & !a);
+  foo ((b || c) & !a);
+  foo (!b & !a);
+  foo (!(b & a));
+  foo (b & (!a));
+  foo (2 & !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) & !a);
+  foo ((2 > c) & !a);
+  foo ((2 == c) & !a);
+  foo ((2 != c) & !a);
+  foo ((2 <= c) & !a);
+  foo ((2 >= c) & !a);
+  foo ((2 && c) & !a);
+  foo ((2 || c) & !a);
+  foo (!2 & !a);
+  foo (!(2 & a));
+  foo (2 & (!a));
+  foo (2 & !1); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) & !1);
+  foo ((2 > c) & !1);
+  foo ((2 == c) & !1);
+  foo ((2 != c) & !1);
+  foo ((2 <= c) & !1);
+  foo ((2 >= c) & !1);
+  foo ((2 && c) & !1);
+  foo ((2 || c) & !1);
+  foo (!2 & !1);
+  foo (!(2 & 1));
+
+  foo (b | !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((b < c) | !a);
+  foo ((b > c) | !a);
+  foo ((b == c) | !a);
+  foo ((b != c) | !a);
+  foo ((b <= c) | !a);
+  foo ((b >= c) | !a);
+  foo ((b && c) | !a);
+  foo ((b || c) | !a);
+  foo (!b | !a);
+  foo (!(b | a));
+  foo (b | (!a));
+  foo (2 | !a); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) | !a);
+  foo ((2 > c) | !a);
+  foo ((2 == c) | !a);
+  foo ((2 != c) | !a);
+  foo ((2 <= c) | !a);
+  foo ((2 >= c) | !a);
+  foo ((2 && c) | !a);
+  foo ((2 || c) | !a);
+  foo (!2 | !a);
+  foo (!(2 | a));
+  foo (2 | (!a));
+  foo (2 | !1); /* { dg-bogus "parentheses" "correct warning" } */
+  foo ((2 < c) | !1);
+  foo ((2 > c) | !1);
+  foo ((2 == c) | !1);
+  foo ((2 != c) | !1);
+  foo ((2 <= c) | !1);
+  foo ((2 >= c) | !1);
+  foo ((2 && c) | !1);
+  foo ((2 || c) | !1);
+  foo (!2 | !1);
+  foo (!(2 | 1));
+  foo (2 | (!1));
+}
+
+int
+baz (int a, int b, int c)
+{
+  foo (!a & (b << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b = c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & ~b);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (b | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & 2);       /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (c = 2)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & ~2);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a & (2 | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (c = 2)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & ~2);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 & (2 | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b = c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | ~b);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (b | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (c = 2)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | ~2);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!a | (2 | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 << c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 >> c));/* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 + c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 - c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (c = 2)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | ~2);      /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 & c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo (!1 | (2 | c)); /* { dg-warning "parentheses" "correct warning" } */
+  foo ((b << c) & !a);
+  foo ((b >> c) & !a);
+  foo ((b + c) & !a);
+  foo ((b - c) & !a);
+  foo ((b = c) & !a);
+  foo (~b & !a);
+  foo ((b & c) & !a);
+  foo ((b | c) & !a);
+  foo ((2 << c) & !a);
+  foo ((2 >> c) & !a);
+  foo ((2 + c) & !a);
+  foo ((2 - c) & !a);
+  foo ((c = 2) & !a);
+  foo (~2 & !a);
+  foo ((2 & c) & !a);
+  foo ((2 | c) & !a);
+  foo ((2 << c) & !1);
+  foo ((2 >> c) & !1);
+  foo ((2 + c) & !1);
+  foo ((2 - c) & !1);
+  foo ((c = 2) & !1);
+  foo (~2 & !1);
+  foo ((2 & c) & !1);
+  foo ((2 | c) & !1);
+  foo ((b << c) | !a);
+  foo ((b >> c) | !a);
+  foo ((b + c) | !a);
+  foo ((b - c) | !a);
+  foo ((b = c) | !a);
+  foo (~b | !a);
+  foo ((b & c) | !a);
+  foo ((b | c) | !a);
+  foo ((2 << c) | !a);
+  foo ((2 >> c) | !a);
+  foo ((2 + c) | !a);
+  foo ((2 - c) | !a);
+  foo ((c = 2) | !a);
+  foo (~2 | !a);
+  foo ((2 & c) | !a);
+  foo ((2 | c) | !a);
+  foo ((2 << c) | !1);
+  foo ((2 >> c) | !1);
+  foo ((2 + c) | !1);
+  foo ((2 - c) | !1);
+  foo ((c = 2) | !1);
+  foo (~2 | !1);
+  foo ((2 & c) | !1);
+  foo ((2 | c) | !1);
+}
index a8edda7..a85b4c6 100644 (file)
@@ -4838,6 +4838,17 @@ extern bool tree_expr_nonzero_warnv_p (tree, bool *);
 
 extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
 
 
 extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
 
+/* Return nonzero if CODE is a tree code that represents a truth value.  */
+static inline bool
+truth_value_p (enum tree_code code)
+{
+  return (TREE_CODE_CLASS (code) == tcc_comparison
+         || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
+         || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
+         || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
+}
+
+
 /* In builtins.c */
 extern tree fold_call_expr (tree, bool);
 extern tree fold_builtin_fputs (tree, tree, bool, bool, tree);
 /* In builtins.c */
 extern tree fold_call_expr (tree, bool);
 extern tree fold_builtin_fputs (tree, tree, bool, bool, tree);
index 1900faa..120a68d 100644 (file)
@@ -1296,7 +1296,7 @@ gimple_stringop_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
     {
       edge_iterator ei;
       for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
     {
       edge_iterator ei;
       for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
-       if (!e34->flags & EDGE_ABNORMAL)
+       if (!(e34->flags & EDGE_ABNORMAL))
          break;
     }
   else
          break;
     }
   else