Index: test/SemaCXX/warn-duplicate-enum.cpp
===================================================================
--- test/SemaCXX/warn-duplicate-enum.cpp	(revision 0)
+++ test/SemaCXX/warn-duplicate-enum.cpp	(revision 0)
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wduplicate-enum
+enum M {
+  M1 = 0,  // expected-note {{element M1 declared here}}
+  M2 = -1,
+  M3,  // expected-warning {{element M3 has been implicitly assigned 0 which previous element M1 has been assigned}}
+  M4};
+
+enum N {
+  N1 = -1,  // expected-note {{element N1 declared here}}
+  N2,       // expected-note {{element N2 declared here}}
+  N3,
+  N4 = -2,
+  N5,  // expected-warning {{element N5 has been implicitly assigned -1 which previous element N1 has been assigned}}
+  N6   // expected-warning {{element N6 has been implicitly assigned 0 which previous element N2 has been assigned}}
+};
+
+enum { O1, O2 = -1, O3 }; // expected-warning{{element O3 has been implicitly assigned 0 which previous element O1 has been assigned}} \
+  // expected-note {{element O1 declared here}}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 160463)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -26,6 +26,10 @@
 def note_identical_enum_values : Note<
   "initialize the last element with the previous element to silence "
   "this warning">;
+def warn_duplicate_enum_values : Warning<
+  "element %0 has been implicitly assigned %1 which previous element %2 has "
+  "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore;
+def note_duplicate_element : Note<"element %0 declared here">;
 
 // Constant expressions
 def err_expr_not_ice : Error<
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 160463)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -10485,6 +10485,39 @@
                                     Next->getName());
 }
 
+// Emits a warning when an element is implicitly set a value that
+// a previous element has already been set to.
+static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements,
+                                        unsigned NumElements, EnumDecl *Enum,
+                                        QualType EnumType) {
+  if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
+                                 Enum->getLocation()) ==
+      DiagnosticsEngine::Ignored)
+    return;
+
+  // Skip diagnostic if previous error were found with the enum.
+  for (unsigned i = 0; i != NumElements; ++i)
+    if (!cast_or_null<EnumConstantDecl>(Elements[i]))
+      return;
+
+  for (unsigned i = 0; i != NumElements; ++i) {
+    EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]);
+    if (ECD->getInitExpr())
+      continue;
+
+    for (unsigned j = 0; j < i; ++j) {
+      EnumConstantDecl *Other = cast<EnumConstantDecl>(Elements[j]);
+      if (llvm::APSInt::isSameValue(Other->getInitVal(), ECD->getInitVal())) {
+        S.Diag(ECD->getLocation(), diag::warn_duplicate_enum_values)
+          << ECD->getName() << ECD->getInitVal().toString(10) 
+          << Other->getName() << ECD->getSourceRange();
+        S.Diag(Other->getLocation(), diag::note_duplicate_element)
+          << Other->getName();
+      }
+    }
+  }
+}
+
 void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
                          SourceLocation RBraceLoc, Decl *EnumDeclX,
                          Decl **Elements, unsigned NumElements,
@@ -10709,6 +10742,7 @@
     DeclsInPrototypeScope.push_back(Enum);
 
   CheckForUniqueEnumValues(*this, Elements, NumElements, Enum, EnumType);
+  CheckForDuplicateEnumValues(*this, Elements, NumElements, Enum, EnumType);
 }
 
 Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
