[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 10:43:04 PDT 2012
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.
- 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/65279b7b/attachment.html>
More information about the cfe-commits
mailing list