Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 131476)
+++ doc/invoke.texi	(working copy)
@@ -248,7 +248,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-multichar  -Wnonnull  -Wno-overflow @gol
 -Woverlength-strings  -Wpacked  -Wpadded @gol
 -Wparentheses  -Wpointer-arith  -Wno-pointer-to-int-cast @gol
--Wredundant-decls @gol
+-Wprecedence -Wredundant-decls @gol
 -Wreturn-type  -Wsequence-point  -Wshadow @gol
 -Wsign-compare  -Wsign-conversion  -Wstack-protector @gol
 -Wstrict-aliasing -Wstrict-aliasing=n @gol
@@ -2941,6 +2941,20 @@ look like this:
 
 This warning is enabled by @option{-Wall}.
 
+@item -Wprecedence
+@opindex Wprecedence
+Warn if parentheses are omitted in when using @samp{&&} and @samp{||} 
+together, where the precedence of these operators may be confusing.
+
+@smallexample
+@group
+@{
+  if (a && b || c && d) 
+    foo ();
+@}
+@end group
+@end smallexample
+
 @item -Wsequence-point
 @opindex Wsequence-point
 Warn about code that may have undefined semantics because of violations
Index: testsuite/gcc.dg/Wparentheses-1.c
===================================================================
--- testsuite/gcc.dg/Wparentheses-1.c	(revision 131476)
+++ testsuite/gcc.dg/Wparentheses-1.c	(working copy)
@@ -1,7 +1,7 @@
 /* Copyright (C) 2001 Free Software Foundation, Inc.  */
 
 /* { dg-do compile } */
-/* { dg-options -Wparentheses } */
+/* { dg-options "-Wprecedence" } */
 
 /* Source: Neil Booth, 1 Nov 2001.  PR 3170, 3422 - bogus warnings
    about suggesting parentheses.  */
Index: testsuite/gcc.dg/Wparentheses-5.c
===================================================================
--- testsuite/gcc.dg/Wparentheses-5.c	(revision 131476)
+++ testsuite/gcc.dg/Wparentheses-5.c	(working copy)
@@ -1,9 +1,9 @@
-/* Test operation of -Wparentheses.  Precedence warnings.  && inside
+/* Test operation of -Wprecedence.  Precedence warnings.  && inside
    ||.  */
 /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
 
 /* { dg-do compile } */
-/* { dg-options "-Wparentheses" } */
+/* { dg-options -Wprecedence } */
 
 int foo (int);
 
Index: testsuite/g++.dg/warn/Wparentheses-8.C
===================================================================
--- testsuite/g++.dg/warn/Wparentheses-8.C	(revision 131476)
+++ testsuite/g++.dg/warn/Wparentheses-8.C	(working copy)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-Wparentheses" }
+// { dg-options -Wprecedence }
 
 // C++ version of gcc.dg/Wparentheses-5.c
 
Index: testsuite/g++.dg/warn/Wparentheses-17.C
===================================================================
--- testsuite/g++.dg/warn/Wparentheses-17.C	(revision 131476)
+++ testsuite/g++.dg/warn/Wparentheses-17.C	(working copy)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-Wparentheses" }
+// { dg-options -Wprecedence }
 
 // Template version of Wparentheses-8.C.
 
Index: testsuite/g++.dg/warn/Wparentheses-5.C
===================================================================
--- testsuite/g++.dg/warn/Wparentheses-5.C	(revision 131476)
+++ testsuite/g++.dg/warn/Wparentheses-5.C	(working copy)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options -Wparentheses }
+// { dg-options "-Wparentheses -Wprecedence" }
 
 // C++ version of gcc.dg/Wparentheses-1.c.
 
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 131476)
+++ cp/typeck.c	(working copy)
@@ -2979,7 +2979,7 @@ build_x_binary_op (enum tree_code code, 
   /* Check for cases such as x+y<<z which users are likely to
      misinterpret.  But don't warn about obj << x + y, since that is a
      common idiom for I/O.  */
-  if (warn_parentheses
+  if ((warn_parentheses || warn_precedence)
       && !processing_template_decl
       && !error_operand_p (arg1)
       && !error_operand_p (arg2)
@@ -6430,7 +6430,7 @@ convert_for_assignment (tree type, tree 
 
   /* If -Wparentheses, warn about a = b = c when a has type bool and b
      does not.  */
-  if (warn_parentheses
+  if ((warn_parentheses || warn_precedence)
       && type == boolean_type_node
       && TREE_CODE (rhs) == MODIFY_EXPR
       && !TREE_NO_WARNING (rhs)
Index: c.opt
===================================================================
--- c.opt	(revision 131476)
+++ c.opt	(working copy)
@@ -377,6 +377,10 @@ Wpragmas
 C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning
 Warn about misuses of pragmas
 
+Wprecedence
+C ObjC C++ ObjC++ Var(warn_precedence) Init(0) Warning
+Warn about confusing operator precedence with && and ||
+
 Wprotocol
 ObjC ObjC++ Var(warn_protocol) Init(1) Warning
 Warn if inherited methods are unimplemented
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 131476)
+++ c-typeck.c	(working copy)
@@ -2755,7 +2755,7 @@ parser_build_binary_op (enum tree_code c
 
   /* Check for cases such as x+y<<z which users are likely
      to misinterpret.  */
-  if (warn_parentheses)
+  if (warn_parentheses || warn_precedence)
     warn_about_parentheses (code, code1, code2);
 
   if (code1 != tcc_comparison)
Index: c-common.c
===================================================================
--- c-common.c	(revision 131476)
+++ c-common.c	(working copy)
@@ -7249,19 +7249,20 @@ warn_array_subscript_with_type_char (tre
     warning (OPT_Wchar_subscripts, "array subscript has type %<char%>");
 }
 
-/* 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.  */
+/* Implement -Wparentheses and -Wprecedence 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.  */
 
 void
 warn_about_parentheses (enum tree_code code, enum tree_code code_left,
 			enum tree_code code_right)
 {
-  if (!warn_parentheses)
+  if (!warn_parentheses && !warn_precedence)
     return;
 
   if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
@@ -7276,7 +7277,7 @@ warn_about_parentheses (enum tree_code c
     {
       if (code_left == TRUTH_ANDIF_EXPR
 	  || code_right == TRUTH_ANDIF_EXPR)
-	warning (OPT_Wparentheses,
+	warning (OPT_Wprecedence,
 		 "suggest parentheses around && within ||");
     }
 
