[PATCH] Allow the warning 'case value not in enumerated type' to be silenced
Dmitri Gribenko
gribozavr at gmail.com
Thu Dec 5 12:39:34 PST 2013
Use ASTContext::hasSameUnqualifiedType().
Hi doug.gregor,
http://llvm-reviews.chandlerc.com/D2334
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D2334?vs=5920&id=5933#toc
Files:
lib/Sema/SemaStmt.cpp
test/Sema/switch.c
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -659,6 +659,29 @@
Val.setIsSigned(IsSigned);
}
+/// Returns true if we should emit a diagnostic about this case expression not
+/// being a part of the enum used in the switch controlling expression.
+static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx,
+ const EnumDecl *ED,
+ const Expr *CaseExpr) {
+ // Don't warn if the 'case' expression refers to a static const variable of
+ // the enum type.
+ CaseExpr = CaseExpr->IgnoreParenImpCasts();
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+ if (!VD->hasGlobalStorage())
+ return true;
+ QualType VarType = VD->getType();
+ if (!VarType.isConstQualified())
+ return true;
+ QualType EnumType = Ctx.getTypeDeclType(ED);
+ if (Ctx.hasSameUnqualifiedType(EnumType, VarType))
+ return false;
+ }
+ }
+ return true;
+}
+
StmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
Stmt *BodyStmt) {
@@ -1008,9 +1031,12 @@
CI != CaseVals.end(); CI++) {
while (EI != EIend && EI->first < CI->first)
EI++;
- if (EI == EIend || EI->first > CI->first)
- Diag(CI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ if (EI == EIend || EI->first > CI->first) {
+ Expr *CaseExpr = CI->second->getLHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
+ }
}
// See which of case ranges aren't in enum
EI = EnumVals.begin();
@@ -1020,18 +1046,23 @@
EI++;
if (EI == EIend || EI->first != RI->first) {
- Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ Expr *CaseExpr = RI->second->getLHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
}
llvm::APSInt Hi =
RI->second->getRHS()->EvaluateKnownConstInt(Context);
AdjustAPSInt(Hi, CondWidth, CondIsSigned);
while (EI != EIend && EI->first < Hi)
EI++;
- if (EI == EIend || EI->first != Hi)
- Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum)
- << CondTypeBeforePromotion;
+ if (EI == EIend || EI->first != Hi) {
+ Expr *CaseExpr = RI->second->getRHS();
+ if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+ Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+ << CondTypeBeforePromotion;
+ }
}
// Check which enum vals aren't in switch
Index: test/Sema/switch.c
===================================================================
--- test/Sema/switch.c
+++ test/Sema/switch.c
@@ -349,3 +349,29 @@
break;
}
}
+
+// Allow the warning 'case value not in enumerated type' to be silenced with
+// the following pattern.
+//
+// If 'case' expression refers to a static const variable of the correct enum
+// type, then we count this as a sufficient declaration of intent by the user,
+// so we silence the warning.
+enum ExtendedEnum1 {
+ EE1_a,
+ EE1_b
+};
+
+enum ExtendedEnum1_unrelated { EE1_misc };
+
+static const enum ExtendedEnum1 EE1_c = 100;
+static const enum ExtendedEnum1_unrelated EE1_d = 101;
+
+void switch_on_ExtendedEnum1(enum ExtendedEnum1 e) {
+ switch(e) {
+ case EE1_a: break;
+ case EE1_b: break;
+ case EE1_c: break; // no-warning
+ case EE1_d: break; // expected-warning {{case value not in enumerated type 'enum ExtendedEnum1'}}
+ }
+}
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2334.2.patch
Type: text/x-patch
Size: 4110 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131205/952bf8d4/attachment.bin>
More information about the cfe-commits
mailing list