diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e8f5ebcca2901d5b9ddfa78beacc8456a9ca13e..d8c08aa99203e4ac6de3994b3dc79d3f3b1ac600 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-12  Ian Lance Taylor  <iant@google.com>
+
+	* fold-const.c (fold_unary): Rename local variable and to
+	and_expr.
+
+	* c-opts.c (c_common_handle_option): For -Wc++-compat set
+	cpp_opts->warn_cxx_operator_names.
+
 2009-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
 
 	PR tree-opt/38865
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index df6fdadf1fb0d9dfa04633fbb72a15c3f8b1722f..0050ab558390f610a8b06007a8232e7b08ebe8d6 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -445,6 +445,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
 	 implies -Wenum-compare.  */
       if (warn_enum_compare == -1 && value)
 	warn_enum_compare = value;
+      cpp_opts->warn_cxx_operator_names = value;
       break;
 
     case OPT_Wdeprecated:
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ab3942fb8dd78aaaa2b1ed27403047d0daa50b40..433ec6085ab10d1986cb6dac7ece4d4e4314eda3 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8290,13 +8290,14 @@ fold_unary (enum tree_code code, tree type, tree op0)
 	  && TREE_CODE (op0) == BIT_AND_EXPR
 	  && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
 	{
-	  tree and = op0;
-	  tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
+	  tree and_expr = op0;
+	  tree and0 = TREE_OPERAND (and_expr, 0);
+	  tree and1 = TREE_OPERAND (and_expr, 1);
 	  int change = 0;
 
-	  if (TYPE_UNSIGNED (TREE_TYPE (and))
+	  if (TYPE_UNSIGNED (TREE_TYPE (and_expr))
 	      || (TYPE_PRECISION (type)
-		  <= TYPE_PRECISION (TREE_TYPE (and))))
+		  <= TYPE_PRECISION (TREE_TYPE (and_expr))))
 	    change = 1;
 	  else if (TYPE_PRECISION (TREE_TYPE (and1))
 		   <= HOST_BITS_PER_WIDE_INT
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8c218933be25625d2f98daac9da5d7b071297b43..8904945838fda71b51efd771819cff6ac14bf2a0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-12  Ian Lance Taylor  <iant@google.com>
+
+	* gcc.dg/Wcxx-compat-13.c: New testcase.
+
 2009-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
 
 	PR tree-opt/38865
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-13.c b/gcc/testsuite/gcc.dg/Wcxx-compat-13.c
new file mode 100644
index 0000000000000000000000000000000000000000..188239644609a6fd13cddfebb5b784c66bbe963e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-13.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+int and;			/* { dg-warning "operator" } */
+int and_eq;			/* { dg-warning "operator" } */
+int bitand;			/* { dg-warning "operator" } */
+int bitor;			/* { dg-warning "operator" } */
+int compl;			/* { dg-warning "operator" } */
+int not;			/* { dg-warning "operator" } */
+int not_eq;			/* { dg-warning "operator" } */
+int or;				/* { dg-warning "operator" } */
+int or_eq;			/* { dg-warning "operator" } */
+int xor;			/* { dg-warning "operator" } */
+int xor_eq;			/* { dg-warning "operator" } */
+
+#define M1 and			/* { dg-warning "operator" } */
+#define M2 and_eq		/* { dg-warning "operator" } */
+#define M3 bitand		/* { dg-warning "operator" } */
+#define M4 bitor		/* { dg-warning "operator" } */
+#define M5 compl		/* { dg-warning "operator" } */
+#define M6 not			/* { dg-warning "operator" } */
+#define M7 not_eq		/* { dg-warning "operator" } */
+#define M8 or			/* { dg-warning "operator" } */
+#define M9 or_eq		/* { dg-warning "operator" } */
+#define M10 xor			/* { dg-warning "operator" } */
+#define M11 xor_eq		/* { dg-warning "operator" } */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 7023582784a975edffbac34ee90bcab3c8cc06bb..263d8441cc94fb333efc75e446bdaf6628df1505 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-12  Ian Lance Taylor  <iant@google.com>
+
+	* include/cpplib.h (struct cpp_options): Add
+	warn_cxx_operator_names field.
+	(NODE_WARN_OPERATOR): Define.
+	(struct cpp_hashnode): Increase flags field to 10 bits, decrease
+	type to 6 bits.
+	* init.c (mark_named_operators): Add flags parameter.
+	(cpp_post_options): Pick flags value to pass to
+	mark_named_operators.
+	* lex.c (lex_identifier): If NODE_WARN_OPERATOR is set, warn that
+	identifier is an operator name in C++.
+
 2009-06-01  Aldy Hernandez  <aldyh@redhat.com>
 
 	* include/line-map.h (LAST_SOURCE_COLUMN): New.
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index effe9a04b1f0a83f7f07d1d0f612e503b062e0c6..a91f1552158603e6431df4c0686a824b3bfb63d1 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -397,6 +397,9 @@ struct cpp_options
   /* Nonzero means handle C++ alternate operator names.  */
   unsigned char operator_names;
 
+  /* Nonzero means warn about use of C++ alternate operator names.  */
+  unsigned char warn_cxx_operator_names;
+
   /* True for traditional preprocessing.  */
   unsigned char traditional;
 
@@ -555,7 +558,8 @@ extern const char *progname;
    identifier that behaves like an operator such as "xor".
    NODE_DIAGNOSTIC is for speed in lex_token: it indicates a
    diagnostic may be required for this node.  Currently this only
-   applies to __VA_ARGS__ and poisoned identifiers.  */
+   applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat
+   warnings about NODE_OPERATOR.  */
 
 /* Hash node flags.  */
 #define NODE_OPERATOR	(1 << 0)	/* C++ named operator.  */
@@ -567,6 +571,7 @@ extern const char *progname;
 #define NODE_MACRO_ARG	(1 << 6)	/* Used during #define processing.  */
 #define NODE_USED	(1 << 7)	/* Dumped with -dU.  */
 #define NODE_CONDITIONAL (1 << 8)	/* Conditional macro */
+#define NODE_WARN_OPERATOR (1 << 9)	/* Warn about C++ named operator.  */
 
 /* Different flavors of hash node.  */
 enum node_type
@@ -636,8 +641,8 @@ struct GTY(()) cpp_hashnode {
 					   then index into directive table.
 					   Otherwise, a NODE_OPERATOR.  */
   unsigned char rid_code;		/* Rid code - for front ends.  */
-  ENUM_BITFIELD(node_type) type : 7;	/* CPP node type.  */
-  unsigned int flags : 9;		/* CPP flags.  */
+  ENUM_BITFIELD(node_type) type : 6;	/* CPP node type.  */
+  unsigned int flags : 10;		/* CPP flags.  */
 
   union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
 };
diff --git a/libcpp/init.c b/libcpp/init.c
index 0f6f49f41da6e1b376e1904165ee01767047c4c1..e5be4e2b1b46375dceaf9d2064d4e53bf09e02af 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -28,7 +28,7 @@ along with this program; see the file COPYING3.  If not see
 #include "localedir.h"
 
 static void init_library (void);
-static void mark_named_operators (cpp_reader *);
+static void mark_named_operators (cpp_reader *, int);
 static void read_original_filename (cpp_reader *);
 static void read_original_directory (cpp_reader *);
 static void post_options (cpp_reader *);
@@ -366,7 +366,7 @@ static const struct builtin_operator operator_array[] =
 
 /* Mark the C++ named operators in the hash table.  */
 static void
-mark_named_operators (cpp_reader *pfile)
+mark_named_operators (cpp_reader *pfile, int flags)
 {
   const struct builtin_operator *b;
 
@@ -375,7 +375,7 @@ mark_named_operators (cpp_reader *pfile)
        b++)
     {
       cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
-      hp->flags |= NODE_OPERATOR;
+      hp->flags |= flags;
       hp->is_directive = 0;
       hp->directive_index = b->value;
     }
@@ -512,13 +512,20 @@ static void sanity_checks (cpp_reader *pfile)
 void
 cpp_post_options (cpp_reader *pfile)
 {
+  int flags;
+
   sanity_checks (pfile);
 
   post_options (pfile);
 
   /* Mark named operators before handling command line macros.  */
+  flags = 0;
   if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
-    mark_named_operators (pfile);
+    flags |= NODE_OPERATOR;
+  if (CPP_OPTION (pfile, warn_cxx_operator_names))
+    flags |= NODE_DIAGNOSTIC | NODE_WARN_OPERATOR;
+  if (flags != 0)
+    mark_named_operators (pfile, flags);
 }
 
 /* Setup for processing input from the file named FNAME, or stdin if
diff --git a/libcpp/lex.c b/libcpp/lex.c
index ca2f2ca06f17d5ed7239e354bd0ff8e5ef053870..bab14a4baa3d761f34f512f0f677071f3abef372 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -560,6 +560,12 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
 	cpp_error (pfile, CPP_DL_PEDWARN,
 		   "__VA_ARGS__ can only appear in the expansion"
 		   " of a C99 variadic macro");
+
+      /* For -Wc++-compat, warn about use of C++ named operators.  */
+      if (result->flags & NODE_WARN_OPERATOR)
+	cpp_error (pfile, CPP_DL_WARNING,
+		   "identifier \"%s\" is a special operator name in C++",
+		   NODE_NAME (result));
     }
 
   return result;