aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2012-05-30 01:01:11 +0000
committerRichard Trieu <rtrieu@google.com>2012-05-30 01:01:11 +0000
commit7af7de7d6b121132dfe8c3b9b5febe2b37aafd62 (patch)
treea8ff942ffd9358d802381be56682c85b218a0467 /lib/Sema/SemaDecl.cpp
parent6fcb3727e31280ba816dc86d024586b8c5933c13 (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.cpp43
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,