blob: 0c0548443224245361f8e3e6f82d691ffa19a32d [file] [log] [blame]
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +00001//==- DeadStores.cpp - Check for stores to dead variables --------*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +00007//
8//===----------------------------------------------------------------------===//
9//
Gabor Greif843e9342008-03-06 10:40:09 +000010// This file defines a DeadStores, a flow-sensitive checker that looks for
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000011// stores to variables that are no longer live.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000015#include "clang/Analysis/LocalCheckers.h"
Ted Kremenekcf6e41b2007-12-21 21:42:19 +000016#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenekfdd225e2007-09-25 04:31:27 +000017#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000018#include "clang/Basic/Diagnostic.h"
Ted Kremenekce1cab92007-09-11 17:24:14 +000019#include "clang/AST/ASTContext.h"
Ted Kremenekc2b51d82008-01-08 18:19:08 +000020#include "llvm/Support/Compiler.h"
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000021
22using namespace clang;
23
24namespace {
Ted Kremenekfdd225e2007-09-25 04:31:27 +000025
Ted Kremenekc2b51d82008-01-08 18:19:08 +000026class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
Chris Lattnerc0508f92007-09-15 23:21:08 +000027 ASTContext &Ctx;
28 Diagnostic &Diags;
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000029public:
Ted Kremenekfdd225e2007-09-25 04:31:27 +000030 DeadStoreObs(ASTContext &ctx,Diagnostic &diags) : Ctx(ctx), Diags(diags){}
31 virtual ~DeadStoreObs() {}
32
33 virtual void ObserveStmt(Stmt* S,
34 const LiveVariables::AnalysisDataTy& AD,
35 const LiveVariables::ValTy& Live) {
Ted Kremenekce1cab92007-09-11 17:24:14 +000036
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000037 if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
Ted Kremenekfdd225e2007-09-25 04:31:27 +000038 if (!B->isAssignmentOp()) return; // Skip non-assignments.
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000039
Ted Kremenekc0576ca2007-09-10 17:36:42 +000040 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
Ted Kremenekc6a1faf2007-09-28 20:48:41 +000041 if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
42 if (VD->hasLocalStorage() && !Live(VD,AD)) {
43 SourceRange R = B->getRHS()->getSourceRange();
Ted Kremenek9c728dc2007-12-12 22:39:36 +000044 Diags.Report(Ctx.getFullLoc(DR->getSourceRange().getBegin()),
45 diag::warn_dead_store, 0, 0, &R, 1);
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000046 }
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000047 }
Ted Kremenekfdd225e2007-09-25 04:31:27 +000048 else if(DeclStmt* DS = dyn_cast<DeclStmt>(S))
49 // Iterate through the decls. Warn if any initializers are complex
50 // expressions that are not live (never used).
Ted Kremenekc0576ca2007-09-10 17:36:42 +000051 for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ;
Ted Kremenekfdd225e2007-09-25 04:31:27 +000052 V = cast_or_null<VarDecl>(V->getNextDeclarator())) {
Ted Kremenekc6a1faf2007-09-28 20:48:41 +000053 if (V->hasLocalStorage())
54 if (Expr* E = V->getInit()) {
55 if (!Live(DS->getDecl(),AD)) {
56 // Special case: check for initializations with constants.
57 //
58 // e.g. : int x = 0;
59 //
60 // If x is EVER assigned a new value later, don't issue
61 // a warning. This is because such initialization can be
62 // due to defensive programming.
63 if (!E->isConstantExpr(Ctx,NULL)) {
64 // Flag a warning.
65 SourceRange R = E->getSourceRange();
Ted Kremenek9c728dc2007-12-12 22:39:36 +000066 Diags.Report(Ctx.getFullLoc(V->getLocation()),
67 diag::warn_dead_store, 0, 0, &R, 1);
Ted Kremenekc6a1faf2007-09-28 20:48:41 +000068 }
Ted Kremenekce1cab92007-09-11 17:24:14 +000069 }
Ted Kremenekfdd225e2007-09-25 04:31:27 +000070 }
Ted Kremenekfdd225e2007-09-25 04:31:27 +000071 }
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000072 }
73};
74
75} // end anonymous namespace
76
77namespace clang {
78
Ted Kremenekbffaa832008-01-29 05:13:23 +000079void CheckDeadStores(CFG& cfg, FunctionDecl& FD, ASTContext &Ctx,
80 Diagnostic &Diags) {
81
82 LiveVariables L(cfg, FD);
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000083 L.runOnCFG(cfg);
Ted Kremenekfdd225e2007-09-25 04:31:27 +000084 DeadStoreObs A(Ctx, Diags);
Ted Kremenek79649df2008-01-17 18:25:22 +000085 L.runOnAllBlocks(cfg,&A);
Ted Kremenek1ed6d2e2007-09-06 23:01:46 +000086}
87
Gabor Greif84675832007-09-11 15:32:40 +000088} // end namespace clang