blob: e898f3ca5715c9c682fb4f32f5036d22e9dfb3e4 [file] [log] [blame]
Ted Kremeneke9646a02007-09-06 23:01:46 +00001//==- DeadStores.cpp - Check for stores to dead variables --------*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This files defines a DeadStores, a flow-sensitive checker that looks for
11// stores to variables that are no longer live.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/Expr.h"
16#include "clang/Analysis/LocalCheckers.h"
17#include "clang/Analysis/LiveVariables.h"
18#include "clang/AST/CFG.h"
19#include "clang/Basic/Diagnostic.h"
20#include "clang/Lex/Preprocessor.h"
Ted Kremenek12789292007-09-11 17:24:14 +000021#include "clang/AST/ASTContext.h"
Ted Kremeneke9646a02007-09-06 23:01:46 +000022
23using namespace clang;
24
25namespace {
26
Ted Kremenekd1d88262007-09-10 15:56:38 +000027class DeadStoreObserver : public LiveVariablesObserver {
Ted Kremeneke9646a02007-09-06 23:01:46 +000028 Preprocessor& PP;
Ted Kremenek12789292007-09-11 17:24:14 +000029 ASTContext Ctx;
Ted Kremeneke9646a02007-09-06 23:01:46 +000030public:
Ted Kremenek12789292007-09-11 17:24:14 +000031 DeadStoreObserver(Preprocessor& pp) :
Chris Lattner409dfd12007-09-13 01:14:03 +000032 PP(pp), Ctx(PP.getSourceManager(), PP.getTargetInfo(),
33 PP.getIdentifierTable()) {
34 }
Ted Kremenek12789292007-09-11 17:24:14 +000035
Ted Kremenekd1d88262007-09-10 15:56:38 +000036 virtual ~DeadStoreObserver() {}
Ted Kremeneke9646a02007-09-06 23:01:46 +000037
Ted Kremenekd1d88262007-09-10 15:56:38 +000038 virtual void ObserveStmt(Stmt* S, LiveVariables& L, llvm::BitVector& Live) {
Ted Kremeneke9646a02007-09-06 23:01:46 +000039 if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
40 // Is this an assignment?
41 if (!B->isAssignmentOp())
42 return;
43
44 // Is this an assignment to a variable?
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000045 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
Ted Kremeneke9646a02007-09-06 23:01:46 +000046 // Is the variable live?
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000047 if (!L.isLive(Live,cast<VarDecl>(DR->getDecl()))) {
Ted Kremeneke9646a02007-09-06 23:01:46 +000048 SourceRange R = B->getRHS()->getSourceRange();
49 PP.getDiagnostics().Report(DR->getSourceRange().Begin(),
50 diag::warn_dead_store, 0, 0,
51 &R,1);
52
53 }
Ted Kremeneke9646a02007-09-06 23:01:46 +000054 }
Ted Kremenek42276bc2007-09-06 23:39:53 +000055 else if(DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
56 // Iterate through the decls. Warn if any of them (which have
57 // initializers) are not live.
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000058 for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ;
Ted Kremenekc0c3d732007-09-11 17:00:40 +000059 V = cast_or_null<VarDecl>(V->getNextDeclarator()))
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000060 if (Expr* E = V->getInit())
Ted Kremenek12789292007-09-11 17:24:14 +000061 if (!L.isLive(Live,V))
62 // Special case: check for initializations with constants.
63 //
64 // e.g. : int x = 0;
65 //
66 // If x is EVER assigned a new value later, don't issue
67 // a warning. This is because such initialization can be
68 // due to defensive programming.
69 if (!E->isConstantExpr(Ctx,NULL) ||
70 L.getVarInfo(V).Kills.size() == 0) {
71 // Flag a warning.
72 SourceRange R = E->getSourceRange();
73 PP.getDiagnostics().Report(V->getLocation(),
74 diag::warn_dead_store, 0, 0,
75 &R,1);
76 }
Ted Kremenek42276bc2007-09-06 23:39:53 +000077 }
Ted Kremeneke9646a02007-09-06 23:01:46 +000078 }
79};
80
81} // end anonymous namespace
82
83namespace clang {
84
85void CheckDeadStores(CFG& cfg, LiveVariables& L, Preprocessor& PP) {
Ted Kremenekd1d88262007-09-10 15:56:38 +000086 DeadStoreObserver A(PP);
Ted Kremeneke9646a02007-09-06 23:01:46 +000087
88 for (CFG::iterator I = cfg.begin(), E = cfg.end(); I != E; ++I)
89 L.runOnBlock(&(*I),&A);
90}
91
92void CheckDeadStores(CFG& cfg, Preprocessor& PP) {
93 LiveVariables L;
94 L.runOnCFG(cfg);
95 CheckDeadStores(cfg,L,PP);
96}
97
Gabor Greif61ce98c2007-09-11 15:32:40 +000098} // end namespace clang