blob: 3c3117cf09bcc5c4e00034b2c8acee0a032e66dc [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
Ted Kremeneke9646a02007-09-06 23:01:46 +000015#include "clang/Analysis/LocalCheckers.h"
16#include "clang/Analysis/LiveVariables.h"
Ted Kremenekd7a2f812007-09-25 04:31:27 +000017#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
Ted Kremeneke9646a02007-09-06 23:01:46 +000018#include "clang/Basic/Diagnostic.h"
Ted Kremenek12789292007-09-11 17:24:14 +000019#include "clang/AST/ASTContext.h"
Ted Kremeneke9646a02007-09-06 23:01:46 +000020
21using namespace clang;
22
23namespace {
Ted Kremenekd7a2f812007-09-25 04:31:27 +000024
25class DeadStoreObs : public LiveVariables::ObserverTy {
Chris Lattner52332d02007-09-15 23:21:08 +000026 ASTContext &Ctx;
27 Diagnostic &Diags;
Ted Kremeneke9646a02007-09-06 23:01:46 +000028public:
Ted Kremenekd7a2f812007-09-25 04:31:27 +000029 DeadStoreObs(ASTContext &ctx,Diagnostic &diags) : Ctx(ctx), Diags(diags){}
30 virtual ~DeadStoreObs() {}
31
32 virtual void ObserveStmt(Stmt* S,
33 const LiveVariables::AnalysisDataTy& AD,
34 const LiveVariables::ValTy& Live) {
Ted Kremenek12789292007-09-11 17:24:14 +000035
Ted Kremeneke9646a02007-09-06 23:01:46 +000036 if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
Ted Kremenekd7a2f812007-09-25 04:31:27 +000037 if (!B->isAssignmentOp()) return; // Skip non-assignments.
Ted Kremeneke9646a02007-09-06 23:01:46 +000038
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000039 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
Ted Kremenek4f200542007-09-28 20:48:41 +000040 if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
41 if (VD->hasLocalStorage() && !Live(VD,AD)) {
42 SourceRange R = B->getRHS()->getSourceRange();
43 Diags.Report(DR->getSourceRange().Begin(), diag::warn_dead_store,
44 0, 0, &R, 1);
Ted Kremeneke9646a02007-09-06 23:01:46 +000045 }
Ted Kremeneke9646a02007-09-06 23:01:46 +000046 }
Ted Kremenekd7a2f812007-09-25 04:31:27 +000047 else if(DeclStmt* DS = dyn_cast<DeclStmt>(S))
48 // Iterate through the decls. Warn if any initializers are complex
49 // expressions that are not live (never used).
Ted Kremenek6b2b4e32007-09-10 17:36:42 +000050 for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ;
Ted Kremenekd7a2f812007-09-25 04:31:27 +000051 V = cast_or_null<VarDecl>(V->getNextDeclarator())) {
Ted Kremenek4f200542007-09-28 20:48:41 +000052 if (V->hasLocalStorage())
53 if (Expr* E = V->getInit()) {
54 if (!Live(DS->getDecl(),AD)) {
55 // Special case: check for initializations with constants.
56 //
57 // e.g. : int x = 0;
58 //
59 // If x is EVER assigned a new value later, don't issue
60 // a warning. This is because such initialization can be
61 // due to defensive programming.
62 if (!E->isConstantExpr(Ctx,NULL)) {
63 // Flag a warning.
64 SourceRange R = E->getSourceRange();
65 Diags.Report(V->getLocation(), diag::warn_dead_store, 0, 0,
66 &R,1);
67 }
Ted Kremenek12789292007-09-11 17:24:14 +000068 }
Ted Kremenekd7a2f812007-09-25 04:31:27 +000069 }
Ted Kremenekd7a2f812007-09-25 04:31:27 +000070 }
Ted Kremeneke9646a02007-09-06 23:01:46 +000071 }
72};
73
74} // end anonymous namespace
75
76namespace clang {
77
Chris Lattner52332d02007-09-15 23:21:08 +000078void CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags) {
Ted Kremeneke9646a02007-09-06 23:01:46 +000079 LiveVariables L;
80 L.runOnCFG(cfg);
Ted Kremenekd7a2f812007-09-25 04:31:27 +000081 DeadStoreObs A(Ctx, Diags);
82 L.runOnAllBlocks(cfg,A);
Ted Kremeneke9646a02007-09-06 23:01:46 +000083}
84
Gabor Greif61ce98c2007-09-11 15:32:40 +000085} // end namespace clang