Index: test/Sema/warn-unique-enum.c
===================================================================
--- test/Sema/warn-unique-enum.c	(revision 0)
+++ test/Sema/warn-unique-enum.c	(revision 0)
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wunique-enum
+
+enum A { A1 = 1, A2 = 1, A3 = 1 };  // expected-warning {{all elements of 'enum A' have value 1}}
+enum { B1 = 1, B2 = 1, B3 = 1 };  // expected-warning {{all elements of anonymous enum have value 1}}
+enum C { C1 = 5 + 4, C2 = C1, C3 = 3 * 3}; // expected-warning {{all elements of 'enum C' have value 9}}
+
+// Don't warn on enums with one element
+enum D { D1 = 4 };
+enum E { E1 };
+
+enum F { F1 = 1, F2 = 1, F3 = 2 };
Index: test/SemaCXX/warn-unique-enum.cpp
===================================================================
--- test/SemaCXX/warn-unique-enum.cpp	(revision 0)
+++ test/SemaCXX/warn-unique-enum.cpp	(revision 0)
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wunique-enum
+
+enum A { A1 = 1, A2 = 1, A3 = 1 };  // expected-warning {{all elements of 'A' have value 1}}
+enum { B1 = 1, B2 = 1, B3 = 1 };  // expected-warning {{all elements of anonymous enum have value 1}}
+enum C { C1 = 5 + 4, C2 = C1, C3 = 3 * 3}; // expected-warning {{all elements of 'C' have value 9}}
+
+// Don't warn on enums with one element
+enum D { D1 = 4 };
+enum E { E1 };
+
+enum F { F1 = 1, F2 = 1, F3 = 2 };
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 156690)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -20,6 +20,10 @@
   "used in loop condition not modified in loop body">,
   InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore;
 
+def warn_identical_enum_values : Warning<
+  "all elements of %select{anonymous enum|%1}0 have value %2">,
+  InGroup<DiagGroup<"unique-enum">>, DefaultIgnore;
+
 // Constant expressions
 def err_expr_not_ice : Error<
   "expression is not an %select{integer|integral}0 constant expression">;
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 156690)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -10257,6 +10257,10 @@
   // Keep track of whether all elements have type int.
   bool AllElementsInt = true;
 
+  // Keep track of whther all the elements have the same value.
+  bool AllElementsEqual = true;
+  llvm::APSInt LastVal;
+
   for (unsigned i = 0; i != NumElements; ++i) {
     EnumConstantDecl *ECD =
       cast_or_null<EnumConstantDecl>(Elements[i]);
@@ -10264,6 +10268,17 @@
 
     const llvm::APSInt &InitVal = ECD->getInitVal();
 
+    // Keep track of whether every enum element is the same value.
+    if (AllElementsEqual && i > 0) {
+      if (InitVal.getBitWidth() > LastVal.getBitWidth())
+        AllElementsEqual = InitVal == LastVal.extend(InitVal.getBitWidth());
+      else if (InitVal.getBitWidth() < LastVal.getBitWidth())
+        AllElementsEqual = InitVal.extend(LastVal.getBitWidth()) == LastVal;
+      else
+        AllElementsEqual = InitVal == LastVal;
+    }
+    LastVal = InitVal;
+
     // Keep track of the size of positive and negative values.
     if (InitVal.isUnsigned() || InitVal.isNonNegative())
       NumPositiveBits = std::max(NumPositiveBits,
@@ -10277,6 +10292,13 @@
       AllElementsInt = ECD->getType() == Context.IntTy;
   }
 
+  if (AllElementsEqual && NumElements > 1) {
+    bool hasIdentifier = Enum->getIdentifier();
+    Diag(EnumLoc, diag::warn_identical_enum_values)
+      << hasIdentifier << EnumType << LastVal.toString(10)
+      << Enum->getSourceRange();
+  }
+
   // Figure out the type that should be used for this enum.
   QualType BestType;
   unsigned BestWidth;
