DeadStoresChecker.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. //==- DeadStoresChecker.cpp - Check for stores to dead variables -*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines a DeadStores, a flow-sensitive checker that looks for
  11. // stores to variables that are no longer live.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "ClangSACheckers.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/Attr.h"
  17. #include "clang/AST/ParentMap.h"
  18. #include "clang/AST/RecursiveASTVisitor.h"
  19. #include "clang/Analysis/Analyses/LiveVariables.h"
  20. #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
  21. #include "clang/StaticAnalyzer/Core/Checker.h"
  22. #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
  23. #include "llvm/ADT/BitVector.h"
  24. #include "llvm/ADT/SmallString.h"
  25. #include "llvm/Support/SaveAndRestore.h"
  26. using namespace clang;
  27. using namespace ento;
  28. namespace {
  29. /// A simple visitor to record what VarDecls occur in EH-handling code.
  30. class EHCodeVisitor : public RecursiveASTVisitor<EHCodeVisitor> {
  31. public:
  32. bool inEH;
  33. llvm::DenseSet<const VarDecl *> &S;
  34. bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
  35. SaveAndRestore<bool> inFinally(inEH, true);
  36. return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtFinallyStmt(S);
  37. }
  38. bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) {
  39. SaveAndRestore<bool> inCatch(inEH, true);
  40. return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtCatchStmt(S);
  41. }
  42. bool TraverseCXXCatchStmt(CXXCatchStmt *S) {
  43. SaveAndRestore<bool> inCatch(inEH, true);
  44. return TraverseStmt(S->getHandlerBlock());
  45. }
  46. bool VisitDeclRefExpr(DeclRefExpr *DR) {
  47. if (inEH)
  48. if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
  49. S.insert(D);
  50. return true;
  51. }
  52. EHCodeVisitor(llvm::DenseSet<const VarDecl *> &S) :
  53. inEH(false), S(S) {}
  54. };
  55. // FIXME: Eventually migrate into its own file, and have it managed by
  56. // AnalysisManager.
  57. class ReachableCode {
  58. const CFG &cfg;
  59. llvm::BitVector reachable;
  60. public:
  61. ReachableCode(const CFG &cfg)
  62. : cfg(cfg), reachable(cfg.getNumBlockIDs(), false) {}
  63. void computeReachableBlocks();
  64. bool isReachable(const CFGBlock *block) const {
  65. return reachable[block->getBlockID()];
  66. }
  67. };
  68. }
  69. void ReachableCode::computeReachableBlocks() {
  70. if (!cfg.getNumBlockIDs())
  71. return;
  72. SmallVector<const CFGBlock*, 10> worklist;
  73. worklist.push_back(&cfg.getEntry());
  74. while (!worklist.empty()) {
  75. const CFGBlock *block = worklist.pop_back_val();
  76. llvm::BitVector::reference isReachable = reachable[block->getBlockID()];
  77. if (isReachable)
  78. continue;
  79. isReachable = true;
  80. for (CFGBlock::const_succ_iterator i = block->succ_begin(),
  81. e = block->succ_end(); i != e; ++i)
  82. if (const CFGBlock *succ = *i)
  83. worklist.push_back(succ);
  84. }
  85. }
  86. static const Expr *
  87. LookThroughTransitiveAssignmentsAndCommaOperators(const Expr *Ex) {
  88. while (Ex) {
  89. const BinaryOperator *BO =
  90. dyn_cast<BinaryOperator>(Ex->IgnoreParenCasts());
  91. if (!BO)
  92. break;
  93. if (BO->getOpcode() == BO_Assign) {
  94. Ex = BO->getRHS();
  95. continue;
  96. }
  97. if (BO->getOpcode() == BO_Comma) {
  98. Ex = BO->getRHS();
  99. continue;
  100. }
  101. break;
  102. }
  103. return Ex;
  104. }
  105. namespace {
  106. class DeadStoreObs : public LiveVariables::Observer {
  107. const CFG &cfg;
  108. ASTContext &Ctx;
  109. BugReporter& BR;
  110. const CheckerBase *Checker;
  111. AnalysisDeclContext* AC;
  112. ParentMap& Parents;
  113. llvm::SmallPtrSet<const VarDecl*, 20> Escaped;
  114. std::unique_ptr<ReachableCode> reachableCode;
  115. const CFGBlock *currentBlock;
  116. std::unique_ptr<llvm::DenseSet<const VarDecl *>> InEH;
  117. enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
  118. public:
  119. DeadStoreObs(const CFG &cfg, ASTContext &ctx, BugReporter &br,
  120. const CheckerBase *checker, AnalysisDeclContext *ac,
  121. ParentMap &parents,
  122. llvm::SmallPtrSet<const VarDecl *, 20> &escaped)
  123. : cfg(cfg), Ctx(ctx), BR(br), Checker(checker), AC(ac), Parents(parents),
  124. Escaped(escaped), currentBlock(nullptr) {}
  125. ~DeadStoreObs() override {}
  126. bool isLive(const LiveVariables::LivenessValues &Live, const VarDecl *D) {
  127. if (Live.isLive(D))
  128. return true;
  129. // Lazily construct the set that records which VarDecls are in
  130. // EH code.
  131. if (!InEH.get()) {
  132. InEH.reset(new llvm::DenseSet<const VarDecl *>());
  133. EHCodeVisitor V(*InEH.get());
  134. V.TraverseStmt(AC->getBody());
  135. }
  136. // Treat all VarDecls that occur in EH code as being "always live"
  137. // when considering to suppress dead stores. Frequently stores
  138. // are followed by reads in EH code, but we don't have the ability
  139. // to analyze that yet.
  140. return InEH->count(D);
  141. }
  142. void Report(const VarDecl *V, DeadStoreKind dsk,
  143. PathDiagnosticLocation L, SourceRange R) {
  144. if (Escaped.count(V))
  145. return;
  146. // Compute reachable blocks within the CFG for trivial cases
  147. // where a bogus dead store can be reported because itself is unreachable.
  148. if (!reachableCode.get()) {
  149. reachableCode.reset(new ReachableCode(cfg));
  150. reachableCode->computeReachableBlocks();
  151. }
  152. if (!reachableCode->isReachable(currentBlock))
  153. return;
  154. SmallString<64> buf;
  155. llvm::raw_svector_ostream os(buf);
  156. const char *BugType = nullptr;
  157. switch (dsk) {
  158. case DeadInit:
  159. BugType = "Dead initialization";
  160. os << "Value stored to '" << *V
  161. << "' during its initialization is never read";
  162. break;
  163. case DeadIncrement:
  164. BugType = "Dead increment";
  165. case Standard:
  166. if (!BugType) BugType = "Dead assignment";
  167. os << "Value stored to '" << *V << "' is never read";
  168. break;
  169. case Enclosing:
  170. // Don't report issues in this case, e.g.: "if (x = foo())",
  171. // where 'x' is unused later. We have yet to see a case where
  172. // this is a real bug.
  173. return;
  174. }
  175. BR.EmitBasicReport(AC->getDecl(), Checker, BugType, "Dead store", os.str(),
  176. L, R);
  177. }
  178. void CheckVarDecl(const VarDecl *VD, const Expr *Ex, const Expr *Val,
  179. DeadStoreKind dsk,
  180. const LiveVariables::LivenessValues &Live) {
  181. if (!VD->hasLocalStorage())
  182. return;
  183. // Reference types confuse the dead stores checker. Skip them
  184. // for now.
  185. if (VD->getType()->getAs<ReferenceType>())
  186. return;
  187. if (!isLive(Live, VD) &&
  188. !(VD->hasAttr<UnusedAttr>() || VD->hasAttr<BlocksAttr>() ||
  189. VD->hasAttr<ObjCPreciseLifetimeAttr>())) {
  190. PathDiagnosticLocation ExLoc =
  191. PathDiagnosticLocation::createBegin(Ex, BR.getSourceManager(), AC);
  192. Report(VD, dsk, ExLoc, Val->getSourceRange());
  193. }
  194. }
  195. void CheckDeclRef(const DeclRefExpr *DR, const Expr *Val, DeadStoreKind dsk,
  196. const LiveVariables::LivenessValues& Live) {
  197. if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
  198. CheckVarDecl(VD, DR, Val, dsk, Live);
  199. }
  200. bool isIncrement(VarDecl *VD, const BinaryOperator* B) {
  201. if (B->isCompoundAssignmentOp())
  202. return true;
  203. const Expr *RHS = B->getRHS()->IgnoreParenCasts();
  204. const BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);
  205. if (!BRHS)
  206. return false;
  207. const DeclRefExpr *DR;
  208. if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
  209. if (DR->getDecl() == VD)
  210. return true;
  211. if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
  212. if (DR->getDecl() == VD)
  213. return true;
  214. return false;
  215. }
  216. void observeStmt(const Stmt *S, const CFGBlock *block,
  217. const LiveVariables::LivenessValues &Live) override {
  218. currentBlock = block;
  219. // Skip statements in macros.
  220. if (S->getLocStart().isMacroID())
  221. return;
  222. // Only cover dead stores from regular assignments. ++/-- dead stores
  223. // have never flagged a real bug.
  224. if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
  225. if (!B->isAssignmentOp()) return; // Skip non-assignments.
  226. if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(B->getLHS()))
  227. if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
  228. // Special case: check for assigning null to a pointer.
  229. // This is a common form of defensive programming.
  230. const Expr *RHS =
  231. LookThroughTransitiveAssignmentsAndCommaOperators(B->getRHS());
  232. RHS = RHS->IgnoreParenCasts();
  233. QualType T = VD->getType();
  234. if (T->isPointerType() || T->isObjCObjectPointerType()) {
  235. if (RHS->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNull))
  236. return;
  237. }
  238. // Special case: self-assignments. These are often used to shut up
  239. // "unused variable" compiler warnings.
  240. if (const DeclRefExpr *RhsDR = dyn_cast<DeclRefExpr>(RHS))
  241. if (VD == dyn_cast<VarDecl>(RhsDR->getDecl()))
  242. return;
  243. // Otherwise, issue a warning.
  244. DeadStoreKind dsk = Parents.isConsumedExpr(B)
  245. ? Enclosing
  246. : (isIncrement(VD,B) ? DeadIncrement : Standard);
  247. CheckVarDecl(VD, DR, B->getRHS(), dsk, Live);
  248. }
  249. }
  250. else if (const UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
  251. if (!U->isIncrementOp() || U->isPrefix())
  252. return;
  253. const Stmt *parent = Parents.getParentIgnoreParenCasts(U);
  254. if (!parent || !isa<ReturnStmt>(parent))
  255. return;
  256. const Expr *Ex = U->getSubExpr()->IgnoreParenCasts();
  257. if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex))
  258. CheckDeclRef(DR, U, DeadIncrement, Live);
  259. }
  260. else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S))
  261. // Iterate through the decls. Warn if any initializers are complex
  262. // expressions that are not live (never used).
  263. for (const auto *DI : DS->decls()) {
  264. const auto *V = dyn_cast<VarDecl>(DI);
  265. if (!V)
  266. continue;
  267. if (V->hasLocalStorage()) {
  268. // Reference types confuse the dead stores checker. Skip them
  269. // for now.
  270. if (V->getType()->getAs<ReferenceType>())
  271. return;
  272. if (const Expr *E = V->getInit()) {
  273. while (const ExprWithCleanups *exprClean =
  274. dyn_cast<ExprWithCleanups>(E))
  275. E = exprClean->getSubExpr();
  276. // Look through transitive assignments, e.g.:
  277. // int x = y = 0;
  278. E = LookThroughTransitiveAssignmentsAndCommaOperators(E);
  279. // Don't warn on C++ objects (yet) until we can show that their
  280. // constructors/destructors don't have side effects.
  281. if (isa<CXXConstructExpr>(E))
  282. return;
  283. // A dead initialization is a variable that is dead after it
  284. // is initialized. We don't flag warnings for those variables
  285. // marked 'unused' or 'objc_precise_lifetime'.
  286. if (!isLive(Live, V) &&
  287. !V->hasAttr<UnusedAttr>() &&
  288. !V->hasAttr<ObjCPreciseLifetimeAttr>()) {
  289. // Special case: check for initializations with constants.
  290. //
  291. // e.g. : int x = 0;
  292. //
  293. // If x is EVER assigned a new value later, don't issue
  294. // a warning. This is because such initialization can be
  295. // due to defensive programming.
  296. if (E->isEvaluatable(Ctx))
  297. return;
  298. if (const DeclRefExpr *DRE =
  299. dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
  300. if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
  301. // Special case: check for initialization from constant
  302. // variables.
  303. //
  304. // e.g. extern const int MyConstant;
  305. // int x = MyConstant;
  306. //
  307. if (VD->hasGlobalStorage() &&
  308. VD->getType().isConstQualified())
  309. return;
  310. // Special case: check for initialization from scalar
  311. // parameters. This is often a form of defensive
  312. // programming. Non-scalars are still an error since
  313. // because it more likely represents an actual algorithmic
  314. // bug.
  315. if (isa<ParmVarDecl>(VD) && VD->getType()->isScalarType())
  316. return;
  317. }
  318. PathDiagnosticLocation Loc =
  319. PathDiagnosticLocation::create(V, BR.getSourceManager());
  320. Report(V, DeadInit, Loc, E->getSourceRange());
  321. }
  322. }
  323. }
  324. }
  325. }
  326. };
  327. } // end anonymous namespace
  328. //===----------------------------------------------------------------------===//
  329. // Driver function to invoke the Dead-Stores checker on a CFG.
  330. //===----------------------------------------------------------------------===//
  331. namespace {
  332. class FindEscaped {
  333. public:
  334. llvm::SmallPtrSet<const VarDecl*, 20> Escaped;
  335. void operator()(const Stmt *S) {
  336. // Check for '&'. Any VarDecl whose address has been taken we treat as
  337. // escaped.
  338. // FIXME: What about references?
  339. const UnaryOperator *U = dyn_cast<UnaryOperator>(S);
  340. if (!U)
  341. return;
  342. if (U->getOpcode() != UO_AddrOf)
  343. return;
  344. const Expr *E = U->getSubExpr()->IgnoreParenCasts();
  345. if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
  346. if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
  347. Escaped.insert(VD);
  348. }
  349. };
  350. } // end anonymous namespace
  351. //===----------------------------------------------------------------------===//
  352. // DeadStoresChecker
  353. //===----------------------------------------------------------------------===//
  354. namespace {
  355. class DeadStoresChecker : public Checker<check::ASTCodeBody> {
  356. public:
  357. void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
  358. BugReporter &BR) const {
  359. // Don't do anything for template instantiations.
  360. // Proving that code in a template instantiation is "dead"
  361. // means proving that it is dead in all instantiations.
  362. // This same problem exists with -Wunreachable-code.
  363. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
  364. if (FD->isTemplateInstantiation())
  365. return;
  366. if (LiveVariables *L = mgr.getAnalysis<LiveVariables>(D)) {
  367. CFG &cfg = *mgr.getCFG(D);
  368. AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D);
  369. ParentMap &pmap = mgr.getParentMap(D);
  370. FindEscaped FS;
  371. cfg.VisitBlockStmts(FS);
  372. DeadStoreObs A(cfg, BR.getContext(), BR, this, AC, pmap, FS.Escaped);
  373. L->runOnAllBlocks(A);
  374. }
  375. }
  376. };
  377. }
  378. void ento::registerDeadStoresChecker(CheckerManager &mgr) {
  379. mgr.registerChecker<DeadStoresChecker>();
  380. }