<br><br><div class="gmail_quote">On Tue, May 29, 2012 at 6:01 PM, Richard Trieu <span dir="ltr"><<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: rtrieu<br>
Date: Tue May 29 20:01:11 2012<br>
New Revision: 157666<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=157666&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=157666&view=rev</a><br>
Log:<br>
Add new -Wunique-enum which will warn on enums which all elements have the<br>
same value and were initialized with literals.  </blockquote><div><br></div><div>This currently produces a false positive on some anonymous-enum'd constants in Diagnostic.h:635:<br><br><pre style="font-size:medium;background-color:rgb(255,255,255)">
  <b><font color="#228B22">enum</font></b> {
    <i><font color="#B22222">/// MaxArguments - The maximum number of arguments we can hold. We currently
</font></i>    <i><font color="#B22222">/// only support up to 10 arguments (%0-%9).  A single diagnostic with more
</font></i>    <i><font color="#B22222">/// than that almost certainly has to be simplified anyway.
</font></i>    MaxArguments = 10,

    <i><font color="#B22222">/// MaxRanges - The maximum number of ranges we can hold.
</font></i>    MaxRanges = 10,

    <i><font color="#B22222">/// MaxFixItHints - The maximum number of ranges we can hold.
</font></i>    MaxFixItHints = 10
  };

<span style="font-family:arial;font-size:small;white-space:normal">Perhaps we should ignore this warning if the enum is unnamed? Or specifically if it's both unnamed and has no instances (so it could still fire on "enum { x, y = 0 } a, b;")<br>
<br>Since this warning is on by default, this breaks a self-host Clang -Werror build.</span></pre><pre style="background-color:rgb(255,255,255)"><font face="arial"><span style="white-space:normal">- David</span></font></pre>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Clang will warn on code like<br>
this:<br>
<br>
enum A {<br>
  FIRST = 1,<br>
  SECOND = 1<br>
};<br>
<br>
<br>
Added:<br>
    cfe/trunk/test/SemaCXX/warn-unique-enum.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/test/Sema/switch.c<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157666&r1=157665&r2=157666&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157666&r1=157665&r2=157666&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 29 20:01:11 2012<br>
@@ -20,6 +20,10 @@<br>
   "used in loop condition not modified in loop body">,<br>
   InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore;<br>
<br>
+def warn_identical_enum_values : Warning<<br>
+  "all elements of %select{anonymous enum|%1}0 are initialized with literals "<br>
+  "to value %2">, InGroup<DiagGroup<"unique-enum">>;<br>
+<br>
 // Constant expressions<br>
 def err_expr_not_ice : Error<<br>
   "expression is not an %select{integer|integral}0 constant expression">;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=157666&r1=157665&r2=157666&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=157666&r1=157665&r2=157666&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 29 20:01:11 2012<br>
@@ -10232,6 +10232,48 @@<br>
   return New;<br>
 }<br>
<br>
+// Emits a warning if every element in the enum is the same value and if<br>
+// every element is initialized with a integer or boolean literal.<br>
+static void CheckForUniqueEnumValues(Sema &S, Decl **Elements,<br>
+                                     unsigned NumElements, EnumDecl *Enum,<br>
+                                     QualType EnumType) {<br>
+  if (S.Diags.getDiagnosticLevel(diag::warn_identical_enum_values,<br>
+                                 Enum->getLocation()) ==<br>
+      DiagnosticsEngine::Ignored)<br>
+    return;<br>
+<br>
+  if (NumElements < 2)<br>
+    return;<br>
+<br>
+  llvm::APSInt FirstVal;<br>
+<br>
+  for (unsigned i = 0; i != NumElements; ++i) {<br>
+    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);<br>
+    if (!ECD)<br>
+      return;<br>
+<br>
+    Expr *InitExpr = ECD->getInitExpr();<br>
+    if (!InitExpr)<br>
+      return;<br>
+    InitExpr = InitExpr->IgnoreImpCasts();<br>
+    if (!isa<IntegerLiteral>(InitExpr) && !isa<CXXBoolLiteralExpr>(InitExpr))<br>
+      return;<br>
+<br>
+    if (i == 0) {<br>
+      FirstVal = ECD->getInitVal();<br>
+      continue;<br>
+    }<br>
+<br>
+    if (FirstVal != ECD->getInitVal())<br>
+      return;<br>
+  }<br>
+<br>
+  bool hasIdentifier = Enum->getIdentifier();<br>
+  S.Diag(Enum->getLocation(), diag::warn_identical_enum_values)<br>
+      << hasIdentifier << EnumType << FirstVal.toString(10)<br>
+      << Enum->getSourceRange();<br>
+}<br>
+<br>
 void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,<br>
                          SourceLocation RBraceLoc, Decl *EnumDeclX,<br>
                          Decl **Elements, unsigned NumElements,<br>
@@ -10455,6 +10497,7 @@<br>
   if (InFunctionDeclarator)<br>
     DeclsInPrototypeScope.push_back(Enum);<br>
<br>
+  CheckForUniqueEnumValues(*this, Elements, NumElements, Enum, EnumType);<br>
 }<br>
<br>
 Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,<br>
<br>
Modified: cfe/trunk/test/Sema/switch.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=157666&r1=157665&r2=157666&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=157666&r1=157665&r2=157666&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/switch.c (original)<br>
+++ cfe/trunk/test/Sema/switch.c Tue May 29 20:01:11 2012<br>
@@ -326,7 +326,7 @@<br>
 void test19(int i) {<br>
   enum {<br>
     kTest19Enum1 = 7,<br>
-    kTest19Enum2 = 7<br>
+    kTest19Enum2 = kTest19Enum1<br>
   };<br>
   const int a = 3;<br>
   switch (i) {<br>
<br>
Added: cfe/trunk/test/SemaCXX/warn-unique-enum.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unique-enum.cpp?rev=157666&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unique-enum.cpp?rev=157666&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/warn-unique-enum.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/warn-unique-enum.cpp Tue May 29 20:01:11 2012<br>
@@ -0,0 +1,16 @@<br>
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wunique-enum<br>
+enum A { A1 = 1, A2 = 1, A3 = 1 };  // expected-warning {{all elements of 'A' are initialized with literals to value 1}}<br>
+enum { B1 = 1, B2 = 1, B3 = 1 };  // expected-warning {{all elements of anonymous enum are initialized with literals to value 1}}<br>
+enum C { C1 = true, C2 = true}; // expected-warning {{all elements of 'C' are initialized with literals to value 1}}<br>
+enum D { D1 = 5, D2 = 5L, D3 = 5UL, D4 = 5LL, D5 = 5ULL };  // expected-warning {{all elements of 'D' are initialized with literals to value 5}}<br>
+<br>
+// Don't warn on enums with less than 2 elements.<br>
+enum E { E1 = 4 };<br>
+enum F { F1 };<br>
+enum G {};<br>
+<br>
+// Don't warn when integer literals do not initialize the elements.<br>
+enum H { H1 = 4, H_MAX = H1, H_MIN = H1 };<br>
+enum I { I1 = H1, I2 = 4 };<br>
+enum J { J1 = 4, J2 = I2 };<br>
+enum K { K1, K2, K3, K4 };<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>