[cfe-commits] r113457 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Checker/PathSensitive/GRCoreEngine.h lib/Checker/GRExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Wed Sep 8 17:40:40 PDT 2010
Author: kremenek
Date: Wed Sep 8 19:40:40 2010
New Revision: 113457
URL: http://llvm.org/viewvc/llvm-project?rev=113457&view=rev
Log:
Static analyzer fix: <rdar://problem/5880430> Switch on enum should not consider default case live if all enum values are covered
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h
cfe/trunk/lib/Checker/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=113457&r1=113456&r2=113457&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Sep 8 19:40:40 2010
@@ -422,6 +422,10 @@
/// ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts();
+ const Expr *IgnoreParenImpCasts() const {
+ return const_cast<Expr*>(this)->IgnoreParenImpCasts();
+ }
+
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h?rev=113457&r1=113456&r2=113457&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h Wed Sep 8 19:40:40 2010
@@ -422,6 +422,10 @@
iterator begin() { return iterator(Src->succ_rbegin()+1); }
iterator end() { return iterator(Src->succ_rend()); }
+ const SwitchStmt *getSwitch() const {
+ return llvm::cast<SwitchStmt>(Src->getTerminator());
+ }
+
ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
ExplodedNode* generateDefaultCaseNode(const GRState* State,
Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=113457&r1=113456&r2=113457&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Wed Sep 8 19:40:40 2010
@@ -1561,9 +1561,24 @@
} while (true);
}
- // If we reach here, than we know that the default branch is
- // possible.
- if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt);
+ if (!defaultIsFeasible)
+ return;
+
+ // If we have switch(enum value), the default branch is not
+ // feasible if all of the enum constants not covered by 'case:' statements
+ // are not feasible values for the switch condition.
+ //
+ // Note that this isn't as accurate as it could be. Even if there isn't
+ // a case for a particular enum value as long as that enum value isn't
+ // feasible then it shouldn't be considered for making 'default:' reachable.
+ const SwitchStmt *SS = builder.getSwitch();
+ const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
+ if (CondExpr->getType()->getAs<EnumType>()) {
+ if (SS->isAllEnumCasesCovered())
+ return;
+ }
+
+ builder.generateDefaultCaseNode(DefaultSt);
}
void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
More information about the cfe-commits
mailing list