[cfe-commits] r157666 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/Sema/switch.c test/SemaCXX/warn-unique-enum.cpp

David Blaikie dblaikie at gmail.com
Wed May 30 11:37:11 PDT 2012


On Wed, May 30, 2012 at 10:43 AM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> On Tue, May 29, 2012 at 6:01 PM, Richard Trieu <rtrieu at google.com> wrote:
>
>> Author: rtrieu
>> Date: Tue May 29 20:01:11 2012
>> New Revision: 157666
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=157666&view=rev
>> Log:
>> Add new -Wunique-enum which will warn on enums which all elements have the
>> same value and were initialized with literals.
>
>
> This currently produces a false positive on some anonymous-enum'd
> constants in Diagnostic.h:635:
>
>   *enum* {
>     */// MaxArguments - The maximum number of arguments we can hold. We currently*    */// only support up to 10 arguments (%0-%9).  A single diagnostic with more*    */// than that almost certainly has to be simplified anyway.*    MaxArguments = 10,
>
>     */// MaxRanges - The maximum number of ranges we can hold.*    MaxRanges = 10,
>
>     */// MaxFixItHints - The maximum number of ranges we can hold.*    MaxFixItHints = 10
>   };
> 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;")
>
> Since this warning is on by default, this breaks a self-host Clang -Werror build.
>
> I've attached a trivial patch to do ignore all unnamed enums for this
warning. If we want to do the smarter thing (only ignore unnamed enums with
no instances) I/we can look into that instead.

- David


> - David
>
> Clang will warn on code like
>> this:
>>
>> enum A {
>>  FIRST = 1,
>>  SECOND = 1
>> };
>>
>>
>> Added:
>>    cfe/trunk/test/SemaCXX/warn-unique-enum.cpp
>> Modified:
>>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>    cfe/trunk/lib/Sema/SemaDecl.cpp
>>    cfe/trunk/test/Sema/switch.c
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157666&r1=157665&r2=157666&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 29
>> 20:01:11 2012
>> @@ -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 are initialized with
>> literals "
>> +  "to value %2">, InGroup<DiagGroup<"unique-enum">>;
>> +
>>  // Constant expressions
>>  def err_expr_not_ice : Error<
>>   "expression is not an %select{integer|integral}0 constant expression">;
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=157666&r1=157665&r2=157666&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 29 20:01:11 2012
>> @@ -10232,6 +10232,48 @@
>>   return New;
>>  }
>>
>> +// Emits a warning if every element in the enum is the same value and if
>> +// every element is initialized with a integer or boolean literal.
>> +static void CheckForUniqueEnumValues(Sema &S, Decl **Elements,
>> +                                     unsigned NumElements, EnumDecl
>> *Enum,
>> +                                     QualType EnumType) {
>> +  if (S.Diags.getDiagnosticLevel(diag::warn_identical_enum_values,
>> +                                 Enum->getLocation()) ==
>> +      DiagnosticsEngine::Ignored)
>> +    return;
>> +
>> +  if (NumElements < 2)
>> +    return;
>> +
>> +  llvm::APSInt FirstVal;
>> +
>> +  for (unsigned i = 0; i != NumElements; ++i) {
>> +    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
>> +    if (!ECD)
>> +      return;
>> +
>> +    Expr *InitExpr = ECD->getInitExpr();
>> +    if (!InitExpr)
>> +      return;
>> +    InitExpr = InitExpr->IgnoreImpCasts();
>> +    if (!isa<IntegerLiteral>(InitExpr) &&
>> !isa<CXXBoolLiteralExpr>(InitExpr))
>> +      return;
>> +
>> +    if (i == 0) {
>> +      FirstVal = ECD->getInitVal();
>> +      continue;
>> +    }
>> +
>> +    if (FirstVal != ECD->getInitVal())
>> +      return;
>> +  }
>> +
>> +  bool hasIdentifier = Enum->getIdentifier();
>> +  S.Diag(Enum->getLocation(), diag::warn_identical_enum_values)
>> +      << hasIdentifier << EnumType << FirstVal.toString(10)
>> +      << Enum->getSourceRange();
>> +}
>> +
>>  void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation
>> LBraceLoc,
>>                          SourceLocation RBraceLoc, Decl *EnumDeclX,
>>                          Decl **Elements, unsigned NumElements,
>> @@ -10455,6 +10497,7 @@
>>   if (InFunctionDeclarator)
>>     DeclsInPrototypeScope.push_back(Enum);
>>
>> +  CheckForUniqueEnumValues(*this, Elements, NumElements, Enum, EnumType);
>>  }
>>
>>  Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
>>
>> Modified: cfe/trunk/test/Sema/switch.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch.c?rev=157666&r1=157665&r2=157666&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Sema/switch.c (original)
>> +++ cfe/trunk/test/Sema/switch.c Tue May 29 20:01:11 2012
>> @@ -326,7 +326,7 @@
>>  void test19(int i) {
>>   enum {
>>     kTest19Enum1 = 7,
>> -    kTest19Enum2 = 7
>> +    kTest19Enum2 = kTest19Enum1
>>   };
>>   const int a = 3;
>>   switch (i) {
>>
>> Added: cfe/trunk/test/SemaCXX/warn-unique-enum.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unique-enum.cpp?rev=157666&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/warn-unique-enum.cpp (added)
>> +++ cfe/trunk/test/SemaCXX/warn-unique-enum.cpp Tue May 29 20:01:11 2012
>> @@ -0,0 +1,16 @@
>> +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wunique-enum
>> +enum A { A1 = 1, A2 = 1, A3 = 1 };  // expected-warning {{all elements
>> of 'A' are initialized with literals to value 1}}
>> +enum { B1 = 1, B2 = 1, B3 = 1 };  // expected-warning {{all elements of
>> anonymous enum are initialized with literals to value 1}}
>> +enum C { C1 = true, C2 = true}; // expected-warning {{all elements of
>> 'C' are initialized with literals to value 1}}
>> +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}}
>> +
>> +// Don't warn on enums with less than 2 elements.
>> +enum E { E1 = 4 };
>> +enum F { F1 };
>> +enum G {};
>> +
>> +// Don't warn when integer literals do not initialize the elements.
>> +enum H { H1 = 4, H_MAX = H1, H_MIN = H1 };
>> +enum I { I1 = H1, I2 = 4 };
>> +enum J { J1 = 4, J2 = I2 };
>> +enum K { K1, K2, K3, K4 };
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120530/0e183629/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: anon_identical_enums.diff
Type: application/octet-stream
Size: 2262 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120530/0e183629/attachment.obj>


More information about the cfe-commits mailing list