blob: f49b125a60a2987425d1959db2a74cacae241073 [file] [log] [blame]
Tom Caredb2fa8a2010-07-06 21:43:29 +00001//==- IdempotentOperationChecker.cpp - Idempotent Operations ----*- 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 set of path-sensitive checks for idempotent and/or
11// tautological operations. Each potential operation is checked along all paths
12// to see if every path results in a pointless operation.
13// +-------------------------------------------+
14// |Table of idempotent/tautological operations|
15// +-------------------------------------------+
16//+--------------------------------------------------------------------------+
17//|Operator | x op x | x op 1 | 1 op x | x op 0 | 0 op x | x op ~0 | ~0 op x |
18//+--------------------------------------------------------------------------+
19// +, += | | | | x | x | |
20// -, -= | | | | x | -x | |
21// *, *= | | x | x | 0 | 0 | |
22// /, /= | 1 | x | | N/A | 0 | |
23// &, &= | x | | | 0 | 0 | x | x
24// |, |= | x | | | x | x | ~0 | ~0
25// ^, ^= | 0 | | | x | x | |
26// <<, <<= | | | | x | 0 | |
27// >>, >>= | | | | x | 0 | |
28// || | 1 | 1 | 1 | x | x | 1 | 1
29// && | 1 | x | x | 0 | 0 | x | x
30// = | x | | | | | |
31// == | 1 | | | | | |
32// >= | 1 | | | | | |
33// <= | 1 | | | | | |
34// > | 0 | | | | | |
35// < | 0 | | | | | |
36// != | 0 | | | | | |
37//===----------------------------------------------------------------------===//
38//
Tom Carea7a8a452010-08-12 22:45:47 +000039// Things TODO:
Tom Caredb2fa8a2010-07-06 21:43:29 +000040// - Improved error messages
41// - Handle mixed assumptions (which assumptions can belong together?)
42// - Finer grained false positive control (levels)
Tom Carea7a8a452010-08-12 22:45:47 +000043// - Handling ~0 values
Tom Caredb2fa8a2010-07-06 21:43:29 +000044
Argyrios Kyrtzidisc9f2e0f2011-02-15 22:55:14 +000045#include "ClangSACheckers.h"
Tom Carea7a8a452010-08-12 22:45:47 +000046#include "clang/Analysis/CFGStmtMap.h"
Tom Caredb34ab72010-08-23 19:51:57 +000047#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
Argyrios Kyrtzidis695fb502011-02-17 21:39:17 +000048#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Ted Kremenek9b663712011-02-10 01:03:03 +000049#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
50#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
51#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
52#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
53#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
54#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
Tom Caredb2fa8a2010-07-06 21:43:29 +000055#include "clang/AST/Stmt.h"
56#include "llvm/ADT/DenseMap.h"
Tom Carea7a8a452010-08-12 22:45:47 +000057#include "llvm/ADT/SmallSet.h"
Ted Kremenek8e376772011-02-14 17:59:20 +000058#include "llvm/ADT/BitVector.h"
Chandler Carruth256565b2010-07-07 00:07:37 +000059#include "llvm/Support/ErrorHandling.h"
Tom Carea7a8a452010-08-12 22:45:47 +000060#include <deque>
Tom Caredb2fa8a2010-07-06 21:43:29 +000061
62using namespace clang;
Ted Kremenek9ef65372010-12-23 07:20:52 +000063using namespace ento;
Tom Caredb2fa8a2010-07-06 21:43:29 +000064
65namespace {
66class IdempotentOperationChecker
67 : public CheckerVisitor<IdempotentOperationChecker> {
Tom Careb0627952010-09-09 02:04:52 +000068public:
69 static void *getTag();
70 void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
71 void PostVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000072 void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, ExprEngine &Eng);
Tom Careb0627952010-09-09 02:04:52 +000073
74private:
75 // Our assumption about a particular operation.
76 enum Assumption { Possible = 0, Impossible, Equal, LHSis1, RHSis1, LHSis0,
77 RHSis0 };
78
79 void UpdateAssumption(Assumption &A, const Assumption &New);
80
81 // False positive reduction methods
82 static bool isSelfAssign(const Expr *LHS, const Expr *RHS);
83 static bool isUnused(const Expr *E, AnalysisContext *AC);
84 static bool isTruncationExtensionAssignment(const Expr *LHS,
85 const Expr *RHS);
Ted Kremenek8e376772011-02-14 17:59:20 +000086 bool pathWasCompletelyAnalyzed(const CFG *cfg,
Tom Careb0627952010-09-09 02:04:52 +000087 const CFGBlock *CB,
Ted Kremenek33d46262010-11-13 05:04:52 +000088 const CFGStmtMap *CBM,
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000089 const CoreEngine &CE);
Tom Careb0627952010-09-09 02:04:52 +000090 static bool CanVary(const Expr *Ex,
91 AnalysisContext *AC);
92 static bool isConstantOrPseudoConstant(const DeclRefExpr *DR,
93 AnalysisContext *AC);
94 static bool containsNonLocalVarDecl(const Stmt *S);
Tom Careb0627952010-09-09 02:04:52 +000095
96 // Hash table and related data structures
97 struct BinaryOperatorData {
98 BinaryOperatorData() : assumption(Possible), analysisContext(0) {}
99
100 Assumption assumption;
101 AnalysisContext *analysisContext;
102 ExplodedNodeSet explodedNodes; // Set of ExplodedNodes that refer to a
103 // BinaryOperator
104 };
105 typedef llvm::DenseMap<const BinaryOperator *, BinaryOperatorData>
106 AssumptionMap;
107 AssumptionMap hash;
108
109 // A class that performs reachability queries for CFGBlocks. Several internal
110 // checks in this checker require reachability information. The requests all
111 // tend to have a common destination, so we lazily do a predecessor search
112 // from the destination node and cache the results to prevent work
113 // duplication.
114 class CFGReachabilityAnalysis {
Ted Kremenek8e376772011-02-14 17:59:20 +0000115 typedef llvm::BitVector ReachableSet;
Tom Careb0627952010-09-09 02:04:52 +0000116 typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
117 ReachableSet analyzed;
118 ReachableMap reachable;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000119 public:
Ted Kremenek8e376772011-02-14 17:59:20 +0000120 CFGReachabilityAnalysis(const CFG &cfg)
121 : analyzed(cfg.getNumBlockIDs(), false) {}
122
Tom Careb0627952010-09-09 02:04:52 +0000123 inline bool isReachable(const CFGBlock *Src, const CFGBlock *Dst);
Tom Caredb2fa8a2010-07-06 21:43:29 +0000124 private:
Tom Careb0627952010-09-09 02:04:52 +0000125 void MapReachability(const CFGBlock *Dst);
126 };
Ted Kremenek8e376772011-02-14 17:59:20 +0000127 llvm::OwningPtr<CFGReachabilityAnalysis> CRA;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000128};
129}
130
131void *IdempotentOperationChecker::getTag() {
132 static int x = 0;
133 return &x;
134}
135
Argyrios Kyrtzidis695fb502011-02-17 21:39:17 +0000136static void RegisterIdempotentOperationChecker(ExprEngine &Eng) {
Tom Caredb2fa8a2010-07-06 21:43:29 +0000137 Eng.registerCheck(new IdempotentOperationChecker());
138}
139
Argyrios Kyrtzidis695fb502011-02-17 21:39:17 +0000140void ento::registerIdempotentOperationChecker(CheckerManager &mgr) {
141 mgr.addCheckerRegisterFunction(RegisterIdempotentOperationChecker);
142}
143
Tom Caredb2fa8a2010-07-06 21:43:29 +0000144void IdempotentOperationChecker::PreVisitBinaryOperator(
145 CheckerContext &C,
146 const BinaryOperator *B) {
Ted Kremenekfe97fa12010-08-02 20:33:02 +0000147 // Find or create an entry in the hash for this BinaryOperator instance.
148 // If we haven't done a lookup before, it will get default initialized to
Tom Care2bbbe502010-09-02 23:30:22 +0000149 // 'Possible'. At this stage we do not store the ExplodedNode, as it has not
150 // been created yet.
151 BinaryOperatorData &Data = hash[B];
152 Assumption &A = Data.assumption;
Tom Care245adab2010-08-18 21:17:24 +0000153 AnalysisContext *AC = C.getCurrentAnalysisContext();
Tom Care2bbbe502010-09-02 23:30:22 +0000154 Data.analysisContext = AC;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000155
156 // If we already have visited this node on a path that does not contain an
157 // idempotent operation, return immediately.
158 if (A == Impossible)
159 return;
160
Tom Carea7a8a452010-08-12 22:45:47 +0000161 // Retrieve both sides of the operator and determine if they can vary (which
162 // may mean this is a false positive.
Tom Caredb2fa8a2010-07-06 21:43:29 +0000163 const Expr *LHS = B->getLHS();
164 const Expr *RHS = B->getRHS();
Tom Care245adab2010-08-18 21:17:24 +0000165
Tom Caredb34ab72010-08-23 19:51:57 +0000166 // At this stage we can calculate whether each side contains a false positive
167 // that applies to all operators. We only need to calculate this the first
168 // time.
169 bool LHSContainsFalsePositive = false, RHSContainsFalsePositive = false;
Tom Care245adab2010-08-18 21:17:24 +0000170 if (A == Possible) {
Tom Caredb34ab72010-08-23 19:51:57 +0000171 // An expression contains a false positive if it can't vary, or if it
172 // contains a known false positive VarDecl.
173 LHSContainsFalsePositive = !CanVary(LHS, AC)
174 || containsNonLocalVarDecl(LHS);
175 RHSContainsFalsePositive = !CanVary(RHS, AC)
176 || containsNonLocalVarDecl(RHS);
Tom Care245adab2010-08-18 21:17:24 +0000177 }
Tom Caredb2fa8a2010-07-06 21:43:29 +0000178
179 const GRState *state = C.getState();
180
181 SVal LHSVal = state->getSVal(LHS);
182 SVal RHSVal = state->getSVal(RHS);
183
184 // If either value is unknown, we can't be 100% sure of all paths.
185 if (LHSVal.isUnknownOrUndef() || RHSVal.isUnknownOrUndef()) {
186 A = Impossible;
187 return;
188 }
189 BinaryOperator::Opcode Op = B->getOpcode();
190
191 // Dereference the LHS SVal if this is an assign operation
192 switch (Op) {
193 default:
194 break;
195
196 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000197 case BO_AddAssign:
198 case BO_SubAssign:
199 case BO_MulAssign:
200 case BO_DivAssign:
201 case BO_AndAssign:
202 case BO_OrAssign:
203 case BO_XorAssign:
204 case BO_ShlAssign:
205 case BO_ShrAssign:
206 case BO_Assign:
Tom Caredb2fa8a2010-07-06 21:43:29 +0000207 // Assign statements have one extra level of indirection
208 if (!isa<Loc>(LHSVal)) {
209 A = Impossible;
210 return;
211 }
Ted Kremenek96ebad62010-09-09 07:13:00 +0000212 LHSVal = state->getSVal(cast<Loc>(LHSVal), LHS->getType());
Tom Caredb2fa8a2010-07-06 21:43:29 +0000213 }
214
215
216 // We now check for various cases which result in an idempotent operation.
217
218 // x op x
219 switch (Op) {
220 default:
221 break; // We don't care about any other operators.
222
223 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000224 case BO_Assign:
Tom Care6216dc02010-08-30 19:25:43 +0000225 // x Assign x can be used to silence unused variable warnings intentionally.
226 // If this is a self assignment and the variable is referenced elsewhere,
Tom Care84c24ed2010-09-07 20:27:56 +0000227 // and the assignment is not a truncation or extension, then it is a false
228 // positive.
Tom Care6216dc02010-08-30 19:25:43 +0000229 if (isSelfAssign(LHS, RHS)) {
Tom Care84c24ed2010-09-07 20:27:56 +0000230 if (!isUnused(LHS, AC) && !isTruncationExtensionAssignment(LHS, RHS)) {
Tom Care6216dc02010-08-30 19:25:43 +0000231 UpdateAssumption(A, Equal);
232 return;
233 }
234 else {
235 A = Impossible;
236 return;
237 }
Tom Caredf4ca422010-07-16 20:41:41 +0000238 }
239
John McCall2de56d12010-08-25 11:45:40 +0000240 case BO_SubAssign:
241 case BO_DivAssign:
242 case BO_AndAssign:
243 case BO_OrAssign:
244 case BO_XorAssign:
245 case BO_Sub:
246 case BO_Div:
247 case BO_And:
248 case BO_Or:
249 case BO_Xor:
250 case BO_LOr:
251 case BO_LAnd:
Tom Care9edd4d02010-08-27 22:50:47 +0000252 case BO_EQ:
253 case BO_NE:
Tom Caredb34ab72010-08-23 19:51:57 +0000254 if (LHSVal != RHSVal || LHSContainsFalsePositive
255 || RHSContainsFalsePositive)
Tom Caredb2fa8a2010-07-06 21:43:29 +0000256 break;
257 UpdateAssumption(A, Equal);
258 return;
259 }
260
261 // x op 1
262 switch (Op) {
263 default:
264 break; // We don't care about any other operators.
265
266 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000267 case BO_MulAssign:
268 case BO_DivAssign:
269 case BO_Mul:
270 case BO_Div:
271 case BO_LOr:
272 case BO_LAnd:
Tom Caredb34ab72010-08-23 19:51:57 +0000273 if (!RHSVal.isConstant(1) || RHSContainsFalsePositive)
Tom Caredb2fa8a2010-07-06 21:43:29 +0000274 break;
275 UpdateAssumption(A, RHSis1);
276 return;
277 }
278
279 // 1 op x
280 switch (Op) {
281 default:
282 break; // We don't care about any other operators.
283
284 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000285 case BO_MulAssign:
286 case BO_Mul:
287 case BO_LOr:
288 case BO_LAnd:
Tom Caredb34ab72010-08-23 19:51:57 +0000289 if (!LHSVal.isConstant(1) || LHSContainsFalsePositive)
Tom Caredb2fa8a2010-07-06 21:43:29 +0000290 break;
291 UpdateAssumption(A, LHSis1);
292 return;
293 }
294
295 // x op 0
296 switch (Op) {
297 default:
298 break; // We don't care about any other operators.
299
300 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000301 case BO_AddAssign:
302 case BO_SubAssign:
303 case BO_MulAssign:
304 case BO_AndAssign:
305 case BO_OrAssign:
306 case BO_XorAssign:
307 case BO_Add:
308 case BO_Sub:
309 case BO_Mul:
310 case BO_And:
311 case BO_Or:
312 case BO_Xor:
313 case BO_Shl:
314 case BO_Shr:
315 case BO_LOr:
316 case BO_LAnd:
Tom Caredb34ab72010-08-23 19:51:57 +0000317 if (!RHSVal.isConstant(0) || RHSContainsFalsePositive)
Tom Caredb2fa8a2010-07-06 21:43:29 +0000318 break;
319 UpdateAssumption(A, RHSis0);
320 return;
321 }
322
323 // 0 op x
324 switch (Op) {
325 default:
326 break; // We don't care about any other operators.
327
328 // Fall through intentional
John McCall2de56d12010-08-25 11:45:40 +0000329 //case BO_AddAssign: // Common false positive
330 case BO_SubAssign: // Check only if unsigned
331 case BO_MulAssign:
332 case BO_DivAssign:
333 case BO_AndAssign:
334 //case BO_OrAssign: // Common false positive
335 //case BO_XorAssign: // Common false positive
336 case BO_ShlAssign:
337 case BO_ShrAssign:
338 case BO_Add:
339 case BO_Sub:
340 case BO_Mul:
341 case BO_Div:
342 case BO_And:
343 case BO_Or:
344 case BO_Xor:
345 case BO_Shl:
346 case BO_Shr:
347 case BO_LOr:
348 case BO_LAnd:
Tom Caredb34ab72010-08-23 19:51:57 +0000349 if (!LHSVal.isConstant(0) || LHSContainsFalsePositive)
Tom Caredb2fa8a2010-07-06 21:43:29 +0000350 break;
351 UpdateAssumption(A, LHSis0);
352 return;
353 }
354
355 // If we get to this point, there has been a valid use of this operation.
356 A = Impossible;
357}
358
Tom Care2bbbe502010-09-02 23:30:22 +0000359// At the post visit stage, the predecessor ExplodedNode will be the
360// BinaryOperator that was just created. We use this hook to collect the
361// ExplodedNode.
362void IdempotentOperationChecker::PostVisitBinaryOperator(
363 CheckerContext &C,
364 const BinaryOperator *B) {
365 // Add the ExplodedNode we just visited
366 BinaryOperatorData &Data = hash[B];
Ted Kremenek020c3742011-02-12 18:50:03 +0000367
368 const Stmt *predStmt
369 = cast<StmtPoint>(C.getPredecessor()->getLocation()).getStmt();
370
371 // Ignore implicit calls to setters.
372 if (isa<ObjCPropertyRefExpr>(predStmt))
373 return;
374
375 assert(isa<BinaryOperator>(predStmt));
Tom Care2bbbe502010-09-02 23:30:22 +0000376 Data.explodedNodes.Add(C.getPredecessor());
377}
378
Tom Caredb2fa8a2010-07-06 21:43:29 +0000379void IdempotentOperationChecker::VisitEndAnalysis(ExplodedGraph &G,
Ted Kremenek3e5637f2010-07-27 18:49:08 +0000380 BugReporter &BR,
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +0000381 ExprEngine &Eng) {
Tom Care2bbbe502010-09-02 23:30:22 +0000382 BugType *BT = new BugType("Idempotent operation", "Dead code");
Tom Caredb2fa8a2010-07-06 21:43:29 +0000383 // Iterate over the hash to see if we have any paths with definite
384 // idempotent operations.
Tom Carea7a8a452010-08-12 22:45:47 +0000385 for (AssumptionMap::const_iterator i = hash.begin(); i != hash.end(); ++i) {
386 // Unpack the hash contents
Tom Care2bbbe502010-09-02 23:30:22 +0000387 const BinaryOperatorData &Data = i->second;
388 const Assumption &A = Data.assumption;
389 AnalysisContext *AC = Data.analysisContext;
390 const ExplodedNodeSet &ES = Data.explodedNodes;
Ted Kremenek3e5637f2010-07-27 18:49:08 +0000391
Tom Carea7a8a452010-08-12 22:45:47 +0000392 const BinaryOperator *B = i->first;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000393
Tom Carea7a8a452010-08-12 22:45:47 +0000394 if (A == Impossible)
395 continue;
396
397 // If the analyzer did not finish, check to see if we can still emit this
398 // warning
399 if (Eng.hasWorkRemaining()) {
400 const CFGStmtMap *CBM = CFGStmtMap::Build(AC->getCFG(),
401 &AC->getParentMap());
402
403 // If we can trace back
Ted Kremenek8e376772011-02-14 17:59:20 +0000404 if (!pathWasCompletelyAnalyzed(AC->getCFG(),
Ted Kremenek33d46262010-11-13 05:04:52 +0000405 CBM->getBlock(B), CBM,
Tom Carea7a8a452010-08-12 22:45:47 +0000406 Eng.getCoreEngine()))
407 continue;
408
409 delete CBM;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000410 }
Tom Carea7a8a452010-08-12 22:45:47 +0000411
Tom Care2bbbe502010-09-02 23:30:22 +0000412 // Select the error message and SourceRanges to report.
Tom Carea7a8a452010-08-12 22:45:47 +0000413 llvm::SmallString<128> buf;
414 llvm::raw_svector_ostream os(buf);
Tom Care2bbbe502010-09-02 23:30:22 +0000415 bool LHSRelevant = false, RHSRelevant = false;
Tom Carea7a8a452010-08-12 22:45:47 +0000416 switch (A) {
417 case Equal:
Tom Care2bbbe502010-09-02 23:30:22 +0000418 LHSRelevant = true;
419 RHSRelevant = true;
John McCall2de56d12010-08-25 11:45:40 +0000420 if (B->getOpcode() == BO_Assign)
Tom Carea7a8a452010-08-12 22:45:47 +0000421 os << "Assigned value is always the same as the existing value";
422 else
423 os << "Both operands to '" << B->getOpcodeStr()
424 << "' always have the same value";
425 break;
426 case LHSis1:
Tom Care2bbbe502010-09-02 23:30:22 +0000427 LHSRelevant = true;
Tom Carea7a8a452010-08-12 22:45:47 +0000428 os << "The left operand to '" << B->getOpcodeStr() << "' is always 1";
429 break;
430 case RHSis1:
Tom Care2bbbe502010-09-02 23:30:22 +0000431 RHSRelevant = true;
Tom Carea7a8a452010-08-12 22:45:47 +0000432 os << "The right operand to '" << B->getOpcodeStr() << "' is always 1";
433 break;
434 case LHSis0:
Tom Care2bbbe502010-09-02 23:30:22 +0000435 LHSRelevant = true;
Tom Carea7a8a452010-08-12 22:45:47 +0000436 os << "The left operand to '" << B->getOpcodeStr() << "' is always 0";
437 break;
438 case RHSis0:
Tom Care2bbbe502010-09-02 23:30:22 +0000439 RHSRelevant = true;
Tom Carea7a8a452010-08-12 22:45:47 +0000440 os << "The right operand to '" << B->getOpcodeStr() << "' is always 0";
441 break;
442 case Possible:
443 llvm_unreachable("Operation was never marked with an assumption");
444 case Impossible:
445 llvm_unreachable(0);
446 }
447
Tom Care2bbbe502010-09-02 23:30:22 +0000448 // Add a report for each ExplodedNode
449 for (ExplodedNodeSet::iterator I = ES.begin(), E = ES.end(); I != E; ++I) {
450 EnhancedBugReport *report = new EnhancedBugReport(*BT, os.str(), *I);
451
452 // Add source ranges and visitor hooks
453 if (LHSRelevant) {
454 const Expr *LHS = i->first->getLHS();
455 report->addRange(LHS->getSourceRange());
456 report->addVisitorCreator(bugreporter::registerVarDeclsLastStore, LHS);
457 }
458 if (RHSRelevant) {
459 const Expr *RHS = i->first->getRHS();
460 report->addRange(i->first->getRHS()->getSourceRange());
461 report->addVisitorCreator(bugreporter::registerVarDeclsLastStore, RHS);
462 }
463
464 BR.EmitReport(report);
465 }
Tom Caredb2fa8a2010-07-06 21:43:29 +0000466 }
467}
468
469// Updates the current assumption given the new assumption
470inline void IdempotentOperationChecker::UpdateAssumption(Assumption &A,
471 const Assumption &New) {
Tom Cared8421ed2010-08-27 22:35:28 +0000472// If the assumption is the same, there is nothing to do
473 if (A == New)
474 return;
475
Tom Caredb2fa8a2010-07-06 21:43:29 +0000476 switch (A) {
477 // If we don't currently have an assumption, set it
478 case Possible:
479 A = New;
480 return;
481
482 // If we have determined that a valid state happened, ignore the new
483 // assumption.
484 case Impossible:
485 return;
486
487 // Any other case means that we had a different assumption last time. We don't
488 // currently support mixing assumptions for diagnostic reasons, so we set
489 // our assumption to be impossible.
490 default:
491 A = Impossible;
492 return;
493 }
494}
495
Tom Care6216dc02010-08-30 19:25:43 +0000496// Check for a statement where a variable is self assigned to possibly avoid an
497// unused variable warning.
498bool IdempotentOperationChecker::isSelfAssign(const Expr *LHS, const Expr *RHS) {
Tom Caredf4ca422010-07-16 20:41:41 +0000499 LHS = LHS->IgnoreParenCasts();
500 RHS = RHS->IgnoreParenCasts();
501
502 const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS);
503 if (!LHS_DR)
504 return false;
505
Tom Careef52bcb2010-08-24 21:09:07 +0000506 const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
507 if (!VD)
Tom Caredf4ca422010-07-16 20:41:41 +0000508 return false;
509
510 const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS);
511 if (!RHS_DR)
512 return false;
513
Tom Careef52bcb2010-08-24 21:09:07 +0000514 if (VD != RHS_DR->getDecl())
515 return false;
516
Tom Care6216dc02010-08-30 19:25:43 +0000517 return true;
518}
519
520// Returns true if the Expr points to a VarDecl that is not read anywhere
521// outside of self-assignments.
522bool IdempotentOperationChecker::isUnused(const Expr *E,
523 AnalysisContext *AC) {
524 if (!E)
525 return false;
526
527 const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
528 if (!DR)
529 return false;
530
531 const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
532 if (!VD)
533 return false;
534
Tom Careef52bcb2010-08-24 21:09:07 +0000535 if (AC->getPseudoConstantAnalysis()->wasReferenced(VD))
536 return false;
537
538 return true;
Tom Caredf4ca422010-07-16 20:41:41 +0000539}
540
541// Check for self casts truncating/extending a variable
542bool IdempotentOperationChecker::isTruncationExtensionAssignment(
543 const Expr *LHS,
544 const Expr *RHS) {
545
546 const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParenCasts());
547 if (!LHS_DR)
548 return false;
549
550 const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
551 if (!VD)
552 return false;
553
554 const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS->IgnoreParenCasts());
555 if (!RHS_DR)
556 return false;
557
558 if (VD != RHS_DR->getDecl())
559 return false;
560
John McCallf6a16482010-12-04 03:47:34 +0000561 return dyn_cast<DeclRefExpr>(RHS->IgnoreParenLValueCasts()) == NULL;
Tom Caredf4ca422010-07-16 20:41:41 +0000562}
563
Tom Carea7a8a452010-08-12 22:45:47 +0000564// Returns false if a path to this block was not completely analyzed, or true
565// otherwise.
Ted Kremenek8e376772011-02-14 17:59:20 +0000566bool
567IdempotentOperationChecker::pathWasCompletelyAnalyzed(const CFG *cfg,
568 const CFGBlock *CB,
569 const CFGStmtMap *CBM,
570 const CoreEngine &CE) {
Ted Kremenekb5318912011-02-15 02:20:03 +0000571
572 if (!CRA.get())
573 CRA.reset(new CFGReachabilityAnalysis(*cfg));
Ted Kremenek8e376772011-02-14 17:59:20 +0000574
Tom Careb0627952010-09-09 02:04:52 +0000575 // Test for reachability from any aborted blocks to this block
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +0000576 typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
Tom Carea7a8a452010-08-12 22:45:47 +0000577 for (AbortedIterator I = CE.blocks_aborted_begin(),
578 E = CE.blocks_aborted_end(); I != E; ++I) {
579 const BlockEdge &BE = I->first;
Tom Caredb2fa8a2010-07-06 21:43:29 +0000580
Tom Carea7a8a452010-08-12 22:45:47 +0000581 // The destination block on the BlockEdge is the first block that was not
Tom Careb0627952010-09-09 02:04:52 +0000582 // analyzed. If we can reach this block from the aborted block, then this
583 // block was not completely analyzed.
Ted Kremeneke8350c62011-02-14 17:59:23 +0000584 //
585 // Also explicitly check if the current block is the destination block.
586 // While technically reachable, it means we aborted the analysis on
587 // a path that included that block.
588 const CFGBlock *destBlock = BE.getDst();
589 if (destBlock == CB || CRA->isReachable(destBlock, CB))
Tom Carea7a8a452010-08-12 22:45:47 +0000590 return false;
Tom Carea7a8a452010-08-12 22:45:47 +0000591 }
Ted Kremenek33d46262010-11-13 05:04:52 +0000592
593 // For the items still on the worklist, see if they are in blocks that
594 // can eventually reach 'CB'.
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +0000595 class VisitWL : public WorkList::Visitor {
Ted Kremenek33d46262010-11-13 05:04:52 +0000596 const CFGStmtMap *CBM;
597 const CFGBlock *TargetBlock;
598 CFGReachabilityAnalysis &CRA;
599 public:
600 VisitWL(const CFGStmtMap *cbm, const CFGBlock *targetBlock,
601 CFGReachabilityAnalysis &cra)
602 : CBM(cbm), TargetBlock(targetBlock), CRA(cra) {}
Ted Kremenek55825aa2011-01-11 02:34:50 +0000603 virtual bool visit(const WorkListUnit &U) {
Ted Kremenek33d46262010-11-13 05:04:52 +0000604 ProgramPoint P = U.getNode()->getLocation();
605 const CFGBlock *B = 0;
606 if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
607 B = CBM->getBlock(SP->getStmt());
608 }
Ted Kremeneked023662010-11-13 05:12:26 +0000609 else if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
610 B = BE->getDst();
611 }
612 else if (BlockEntrance *BEnt = dyn_cast<BlockEntrance>(&P)) {
613 B = BEnt->getBlock();
614 }
615 else if (BlockExit *BExit = dyn_cast<BlockExit>(&P)) {
616 B = BExit->getBlock();
617 }
Ted Kremenek33d46262010-11-13 05:04:52 +0000618 if (!B)
619 return true;
620
621 return CRA.isReachable(B, TargetBlock);
622 }
623 };
Ted Kremenek8e376772011-02-14 17:59:20 +0000624 VisitWL visitWL(CBM, CB, *CRA.get());
Ted Kremenek33d46262010-11-13 05:04:52 +0000625 // Were there any items in the worklist that could potentially reach
626 // this block?
Ted Kremenek55825aa2011-01-11 02:34:50 +0000627 if (CE.getWorkList()->visitItemsInWorkList(visitWL))
Ted Kremenek33d46262010-11-13 05:04:52 +0000628 return false;
Tom Carea7a8a452010-08-12 22:45:47 +0000629
Tom Careb0627952010-09-09 02:04:52 +0000630 // Verify that this block is reachable from the entry block
Ted Kremenek8e376772011-02-14 17:59:20 +0000631 if (!CRA->isReachable(&cfg->getEntry(), CB))
Tom Careb0627952010-09-09 02:04:52 +0000632 return false;
633
Tom Carea7a8a452010-08-12 22:45:47 +0000634 // If we get to this point, there is no connection to the entry block or an
635 // aborted block. This path is unreachable and we can report the error.
636 return true;
637}
638
639// Recursive function that determines whether an expression contains any element
640// that varies. This could be due to a compile-time constant like sizeof. An
641// expression may also involve a variable that behaves like a constant. The
642// function returns true if the expression varies, and false otherwise.
Tom Care245adab2010-08-18 21:17:24 +0000643bool IdempotentOperationChecker::CanVary(const Expr *Ex,
644 AnalysisContext *AC) {
Tom Carea7a8a452010-08-12 22:45:47 +0000645 // Parentheses and casts are irrelevant here
646 Ex = Ex->IgnoreParenCasts();
647
648 if (Ex->getLocStart().isMacroID())
649 return false;
650
651 switch (Ex->getStmtClass()) {
652 // Trivially true cases
653 case Stmt::ArraySubscriptExprClass:
654 case Stmt::MemberExprClass:
655 case Stmt::StmtExprClass:
656 case Stmt::CallExprClass:
657 case Stmt::VAArgExprClass:
658 case Stmt::ShuffleVectorExprClass:
659 return true;
660 default:
661 return true;
662
663 // Trivially false cases
664 case Stmt::IntegerLiteralClass:
665 case Stmt::CharacterLiteralClass:
666 case Stmt::FloatingLiteralClass:
667 case Stmt::PredefinedExprClass:
668 case Stmt::ImaginaryLiteralClass:
669 case Stmt::StringLiteralClass:
670 case Stmt::OffsetOfExprClass:
671 case Stmt::CompoundLiteralExprClass:
672 case Stmt::AddrLabelExprClass:
Francois Pichetf1872372010-12-08 22:35:30 +0000673 case Stmt::BinaryTypeTraitExprClass:
Tom Carea7a8a452010-08-12 22:45:47 +0000674 case Stmt::GNUNullExprClass:
675 case Stmt::InitListExprClass:
676 case Stmt::DesignatedInitExprClass:
677 case Stmt::BlockExprClass:
678 case Stmt::BlockDeclRefExprClass:
679 return false;
680
681 // Cases requiring custom logic
682 case Stmt::SizeOfAlignOfExprClass: {
683 const SizeOfAlignOfExpr *SE = cast<const SizeOfAlignOfExpr>(Ex);
684 if (!SE->isSizeOf())
685 return false;
686 return SE->getTypeOfArgument()->isVariableArrayType();
687 }
688 case Stmt::DeclRefExprClass:
Tom Care6216dc02010-08-30 19:25:43 +0000689 // Check for constants/pseudoconstants
Tom Care245adab2010-08-18 21:17:24 +0000690 return !isConstantOrPseudoConstant(cast<DeclRefExpr>(Ex), AC);
Tom Carea7a8a452010-08-12 22:45:47 +0000691
692 // The next cases require recursion for subexpressions
693 case Stmt::BinaryOperatorClass: {
694 const BinaryOperator *B = cast<const BinaryOperator>(Ex);
Ted Kremenek74faec22010-10-29 01:06:54 +0000695
696 // Exclude cases involving pointer arithmetic. These are usually
697 // false positives.
698 if (B->getOpcode() == BO_Sub || B->getOpcode() == BO_Add)
699 if (B->getLHS()->getType()->getAs<PointerType>())
700 return false;
701
Tom Care245adab2010-08-18 21:17:24 +0000702 return CanVary(B->getRHS(), AC)
703 || CanVary(B->getLHS(), AC);
Tom Carea7a8a452010-08-12 22:45:47 +0000704 }
705 case Stmt::UnaryOperatorClass: {
706 const UnaryOperator *U = cast<const UnaryOperator>(Ex);
Eli Friedmande7e6622010-08-13 01:36:11 +0000707 // Handle trivial case first
Tom Carea7a8a452010-08-12 22:45:47 +0000708 switch (U->getOpcode()) {
John McCall2de56d12010-08-25 11:45:40 +0000709 case UO_Extension:
Tom Carea7a8a452010-08-12 22:45:47 +0000710 return false;
711 default:
Tom Care245adab2010-08-18 21:17:24 +0000712 return CanVary(U->getSubExpr(), AC);
Tom Carea7a8a452010-08-12 22:45:47 +0000713 }
714 }
715 case Stmt::ChooseExprClass:
Tom Care245adab2010-08-18 21:17:24 +0000716 return CanVary(cast<const ChooseExpr>(Ex)->getChosenSubExpr(
717 AC->getASTContext()), AC);
Tom Carea7a8a452010-08-12 22:45:47 +0000718 case Stmt::ConditionalOperatorClass:
John McCall56ca35d2011-02-17 10:25:35 +0000719 case Stmt::BinaryConditionalOperatorClass:
720 return CanVary(cast<AbstractConditionalOperator>(Ex)->getCond(), AC);
Tom Carea7a8a452010-08-12 22:45:47 +0000721 }
Tom Caredb2fa8a2010-07-06 21:43:29 +0000722}
723
Tom Care245adab2010-08-18 21:17:24 +0000724// Returns true if a DeclRefExpr is or behaves like a constant.
725bool IdempotentOperationChecker::isConstantOrPseudoConstant(
Tom Care6216dc02010-08-30 19:25:43 +0000726 const DeclRefExpr *DR,
727 AnalysisContext *AC) {
Tom Care245adab2010-08-18 21:17:24 +0000728 // Check if the type of the Decl is const-qualified
729 if (DR->getType().isConstQualified())
730 return true;
731
Tom Care50e8ac22010-08-16 21:43:52 +0000732 // Check for an enum
733 if (isa<EnumConstantDecl>(DR->getDecl()))
734 return true;
735
Tom Caredb34ab72010-08-23 19:51:57 +0000736 const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
737 if (!VD)
Tom Care245adab2010-08-18 21:17:24 +0000738 return true;
739
Tom Caredb34ab72010-08-23 19:51:57 +0000740 // Check if the Decl behaves like a constant. This check also takes care of
741 // static variables, which can only change between function calls if they are
742 // modified in the AST.
743 PseudoConstantAnalysis *PCA = AC->getPseudoConstantAnalysis();
744 if (PCA->isPseudoConstant(VD))
745 return true;
746
747 return false;
748}
749
750// Recursively find any substatements containing VarDecl's with storage other
751// than local
752bool IdempotentOperationChecker::containsNonLocalVarDecl(const Stmt *S) {
753 const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
754
755 if (DR)
756 if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
757 if (!VD->hasLocalStorage())
758 return true;
759
760 for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
761 ++I)
762 if (const Stmt *child = *I)
763 if (containsNonLocalVarDecl(child))
764 return true;
765
Tom Care50e8ac22010-08-16 21:43:52 +0000766 return false;
767}
Tom Careb0627952010-09-09 02:04:52 +0000768
Tom Careb0627952010-09-09 02:04:52 +0000769bool IdempotentOperationChecker::CFGReachabilityAnalysis::isReachable(
770 const CFGBlock *Src,
771 const CFGBlock *Dst) {
772 const unsigned DstBlockID = Dst->getBlockID();
773
774 // If we haven't analyzed the destination node, run the analysis now
Ted Kremenek8e376772011-02-14 17:59:20 +0000775 if (!analyzed[DstBlockID]) {
Tom Careb0627952010-09-09 02:04:52 +0000776 MapReachability(Dst);
Ted Kremenek8e376772011-02-14 17:59:20 +0000777 analyzed[DstBlockID] = true;
Tom Careb0627952010-09-09 02:04:52 +0000778 }
779
780 // Return the cached result
Ted Kremenek8e376772011-02-14 17:59:20 +0000781 return reachable[DstBlockID][Src->getBlockID()];
Tom Careb0627952010-09-09 02:04:52 +0000782}
783
784// Maps reachability to a common node by walking the predecessors of the
785// destination node.
786void IdempotentOperationChecker::CFGReachabilityAnalysis::MapReachability(
787 const CFGBlock *Dst) {
Ted Kremenek8e376772011-02-14 17:59:20 +0000788
789 llvm::SmallVector<const CFGBlock *, 11> worklist;
790 llvm::BitVector visited(analyzed.size());
791
Tom Careb0627952010-09-09 02:04:52 +0000792 ReachableSet &DstReachability = reachable[Dst->getBlockID()];
Ted Kremenek8e376772011-02-14 17:59:20 +0000793 DstReachability.resize(analyzed.size(), false);
Tom Careb0627952010-09-09 02:04:52 +0000794
795 // Start searching from the destination node, since we commonly will perform
796 // multiple queries relating to a destination node.
Ted Kremenek8e376772011-02-14 17:59:20 +0000797 worklist.push_back(Dst);
Tom Careb0627952010-09-09 02:04:52 +0000798 bool firstRun = true;
Tom Careb0627952010-09-09 02:04:52 +0000799
Ted Kremenek8e376772011-02-14 17:59:20 +0000800 while (!worklist.empty()) {
801 const CFGBlock *block = worklist.back();
802 worklist.pop_back();
803
804 if (visited[block->getBlockID()])
805 continue;
806 visited[block->getBlockID()] = true;
807
Tom Careb0627952010-09-09 02:04:52 +0000808 // Update reachability information for this node -> Dst
Ted Kremenek8e376772011-02-14 17:59:20 +0000809 if (!firstRun) {
Tom Careb0627952010-09-09 02:04:52 +0000810 // Don't insert Dst -> Dst unless it was a predecessor of itself
Ted Kremenek8e376772011-02-14 17:59:20 +0000811 DstReachability[block->getBlockID()] = true;
812 }
Tom Careb0627952010-09-09 02:04:52 +0000813 else
814 firstRun = false;
815
Ted Kremenek8e376772011-02-14 17:59:20 +0000816 // Add the predecessors to the worklist.
817 for (CFGBlock::const_pred_iterator i = block->pred_begin(),
818 e = block->pred_end(); i != e; ++i) {
819 worklist.push_back(*i);
820 }
Tom Careb0627952010-09-09 02:04:52 +0000821 }
822}