diff options
author | Richard Trieu <rtrieu@google.com> | 2012-05-30 01:01:11 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2012-05-30 01:01:11 +0000 |
commit | 7af7de7d6b121132dfe8c3b9b5febe2b37aafd62 (patch) | |
tree | a8ff942ffd9358d802381be56682c85b218a0467 /lib/Sema/SemaDecl.cpp | |
parent | 6fcb3727e31280ba816dc86d024586b8c5933c13 (diff) |
Add new -Wunique-enum which will warn on enums which all elements have the
same value and were initialized with literals. Clang will warn on code like
this:
enum A {
FIRST = 1,
SECOND = 1
};
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157666 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 036907b685..8f991c7fe1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -10232,6 +10232,48 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, 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 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, if (InFunctionDeclarator) DeclsInPrototypeScope.push_back(Enum); + CheckForUniqueEnumValues(*this, Elements, NumElements, Enum, EnumType); } Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, |