blob: 8ebee9614ac4b261ffac460f01b2f325e1b5027d [file] [log] [blame]
Ted Kremeneka0a5ca12011-03-15 03:17:07 +00001//==- UninitializedValues.cpp - Find Uninitialized Values -------*- C++ --*-==//
Ted Kremenekb749a6d2011-01-15 02:58:47 +00002//
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 implements uninitialized values analysis for source-level CFGs.
11//
12//===----------------------------------------------------------------------===//
13
Ted Kremenekb82ddd62011-01-20 17:37:17 +000014#include <utility>
Ted Kremenekb749a6d2011-01-15 02:58:47 +000015#include "llvm/ADT/Optional.h"
16#include "llvm/ADT/SmallVector.h"
Argyrios Kyrtzidisb3483b32011-05-31 03:56:09 +000017#include "llvm/ADT/PackedVector.h"
Ted Kremenekb749a6d2011-01-15 02:58:47 +000018#include "llvm/ADT/DenseMap.h"
Richard Smith130b8d42012-07-13 23:33:44 +000019#include "clang/AST/ASTContext.h"
Ted Kremenekb749a6d2011-01-15 02:58:47 +000020#include "clang/AST/Decl.h"
21#include "clang/Analysis/CFG.h"
Ted Kremenekbcf848f2011-01-25 19:13:48 +000022#include "clang/Analysis/AnalysisContext.h"
Ted Kremenekb749a6d2011-01-15 02:58:47 +000023#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
Ted Kremeneka0a5ca12011-03-15 03:17:07 +000024#include "clang/Analysis/Analyses/UninitializedValues.h"
Ted Kremenekedf22ed2012-09-13 00:21:35 +000025#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
Argyrios Kyrtzidis981a9612012-03-01 19:45:56 +000026#include "llvm/Support/SaveAndRestore.h"
Ted Kremenekb749a6d2011-01-15 02:58:47 +000027
28using namespace clang;
29
Richard Smith130b8d42012-07-13 23:33:44 +000030#define DEBUG_LOGGING 0
31
Ted Kremenek93a31382011-01-27 02:29:34 +000032static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
Ted Kremenekc15a4e42011-03-17 03:06:11 +000033 if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() &&
Ted Kremenek97c39382011-04-07 20:02:56 +000034 !vd->isExceptionVariable() &&
Ted Kremenekc15a4e42011-03-17 03:06:11 +000035 vd->getDeclContext() == dc) {
36 QualType ty = vd->getType();
37 return ty->isScalarType() || ty->isVectorType();
38 }
39 return false;
Ted Kremenekcab479f2011-01-18 04:53:25 +000040}
41
Ted Kremenekb749a6d2011-01-15 02:58:47 +000042//------------------------------------------------------------------------====//
Ted Kremeneka895fe92011-03-15 04:57:27 +000043// DeclToIndex: a mapping from Decls we track to value indices.
Ted Kremenekb749a6d2011-01-15 02:58:47 +000044//====------------------------------------------------------------------------//
45
46namespace {
Ted Kremeneka895fe92011-03-15 04:57:27 +000047class DeclToIndex {
Ted Kremenekb749a6d2011-01-15 02:58:47 +000048 llvm::DenseMap<const VarDecl *, unsigned> map;
49public:
Ted Kremeneka895fe92011-03-15 04:57:27 +000050 DeclToIndex() {}
Ted Kremenekb749a6d2011-01-15 02:58:47 +000051
52 /// Compute the actual mapping from declarations to bits.
53 void computeMap(const DeclContext &dc);
54
55 /// Return the number of declarations in the map.
56 unsigned size() const { return map.size(); }
57
58 /// Returns the bit vector index for a given declaration.
Ted Kremenek03325c42011-03-29 01:40:00 +000059 llvm::Optional<unsigned> getValueIndex(const VarDecl *d) const;
Ted Kremenekb749a6d2011-01-15 02:58:47 +000060};
61}
62
Ted Kremeneka895fe92011-03-15 04:57:27 +000063void DeclToIndex::computeMap(const DeclContext &dc) {
Ted Kremenekb749a6d2011-01-15 02:58:47 +000064 unsigned count = 0;
65 DeclContext::specific_decl_iterator<VarDecl> I(dc.decls_begin()),
66 E(dc.decls_end());
67 for ( ; I != E; ++I) {
David Blaikie40ed2972012-06-06 20:45:41 +000068 const VarDecl *vd = *I;
Ted Kremenek93a31382011-01-27 02:29:34 +000069 if (isTrackedVar(vd, &dc))
Ted Kremenekb749a6d2011-01-15 02:58:47 +000070 map[vd] = count++;
71 }
72}
73
Ted Kremenek03325c42011-03-29 01:40:00 +000074llvm::Optional<unsigned> DeclToIndex::getValueIndex(const VarDecl *d) const {
75 llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I = map.find(d);
Ted Kremenekb749a6d2011-01-15 02:58:47 +000076 if (I == map.end())
77 return llvm::Optional<unsigned>();
78 return I->second;
79}
80
81//------------------------------------------------------------------------====//
82// CFGBlockValues: dataflow values for CFG blocks.
83//====------------------------------------------------------------------------//
84
Ted Kremenekc8c4e5f2011-03-15 04:57:38 +000085// These values are defined in such a way that a merge can be done using
86// a bitwise OR.
87enum Value { Unknown = 0x0, /* 00 */
88 Initialized = 0x1, /* 01 */
89 Uninitialized = 0x2, /* 10 */
90 MayUninitialized = 0x3 /* 11 */ };
91
92static bool isUninitialized(const Value v) {
93 return v >= Uninitialized;
94}
95static bool isAlwaysUninit(const Value v) {
96 return v == Uninitialized;
97}
Ted Kremenekd3def382011-03-15 04:57:29 +000098
Benjamin Kramer8aef5962011-03-26 12:38:21 +000099namespace {
Ted Kremenek9b15c962011-03-15 04:57:32 +0000100
Argyrios Kyrtzidisb3483b32011-05-31 03:56:09 +0000101typedef llvm::PackedVector<Value, 2> ValueVector;
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000102
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000103class CFGBlockValues {
104 const CFG &cfg;
Ted Kremenek6080d322012-07-19 04:59:05 +0000105 std::vector<ValueVector*> vals;
Ted Kremeneka895fe92011-03-15 04:57:27 +0000106 ValueVector scratch;
Ted Kremeneke3ae0a42011-03-15 05:30:12 +0000107 DeclToIndex declToIndex;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000108public:
109 CFGBlockValues(const CFG &cfg);
110 ~CFGBlockValues();
Ted Kremenek6080d322012-07-19 04:59:05 +0000111
Ted Kremenek37881932011-04-04 23:29:12 +0000112 unsigned getNumEntries() const { return declToIndex.size(); }
113
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000114 void computeSetOfDeclarations(const DeclContext &dc);
Ted Kremenek6080d322012-07-19 04:59:05 +0000115 ValueVector &getValueVector(const CFGBlock *block) {
116 return *vals[block->getBlockID()];
117 }
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000118
Richard Smithb721e302012-07-02 23:23:04 +0000119 void setAllScratchValues(Value V);
Ted Kremeneka895fe92011-03-15 04:57:27 +0000120 void mergeIntoScratch(ValueVector const &source, bool isFirst);
121 bool updateValueVectorWithScratch(const CFGBlock *block);
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000122
123 bool hasNoDeclarations() const {
Ted Kremeneke3ae0a42011-03-15 05:30:12 +0000124 return declToIndex.size() == 0;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000125 }
Ted Kremenek417d5662011-08-20 01:15:28 +0000126
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000127 void resetScratch();
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000128
Ted Kremeneka895fe92011-03-15 04:57:27 +0000129 ValueVector::reference operator[](const VarDecl *vd);
Richard Smith4323bf82012-05-25 02:17:09 +0000130
131 Value getValue(const CFGBlock *block, const CFGBlock *dstBlock,
132 const VarDecl *vd) {
133 const llvm::Optional<unsigned> &idx = declToIndex.getValueIndex(vd);
134 assert(idx.hasValue());
Ted Kremenek6080d322012-07-19 04:59:05 +0000135 return getValueVector(block)[idx.getValue()];
Richard Smith4323bf82012-05-25 02:17:09 +0000136 }
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000137};
Benjamin Kramer8aef5962011-03-26 12:38:21 +0000138} // end anonymous namespace
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000139
Ted Kremenek6080d322012-07-19 04:59:05 +0000140CFGBlockValues::CFGBlockValues(const CFG &c) : cfg(c), vals(0) {}
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000141
142CFGBlockValues::~CFGBlockValues() {
Ted Kremenek6080d322012-07-19 04:59:05 +0000143 for (std::vector<ValueVector*>::iterator I = vals.begin(), E = vals.end();
144 I != E; ++I)
145 delete *I;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000146}
147
148void CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) {
Ted Kremeneke3ae0a42011-03-15 05:30:12 +0000149 declToIndex.computeMap(dc);
Ted Kremenek6080d322012-07-19 04:59:05 +0000150 unsigned decls = declToIndex.size();
151 scratch.resize(decls);
152 unsigned n = cfg.getNumBlockIDs();
153 if (!n)
154 return;
155 vals.resize(n);
156 for (unsigned i = 0; i < n; ++i)
157 vals[i] = new ValueVector(decls);
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000158}
159
Richard Smith130b8d42012-07-13 23:33:44 +0000160#if DEBUG_LOGGING
Ted Kremeneka895fe92011-03-15 04:57:27 +0000161static void printVector(const CFGBlock *block, ValueVector &bv,
Ted Kremenekba357292011-02-01 17:43:18 +0000162 unsigned num) {
Ted Kremenekba357292011-02-01 17:43:18 +0000163 llvm::errs() << block->getBlockID() << " :";
164 for (unsigned i = 0; i < bv.size(); ++i) {
165 llvm::errs() << ' ' << bv[i];
166 }
167 llvm::errs() << " : " << num << '\n';
168}
169#endif
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000170
Richard Smithb721e302012-07-02 23:23:04 +0000171void CFGBlockValues::setAllScratchValues(Value V) {
172 for (unsigned I = 0, E = scratch.size(); I != E; ++I)
173 scratch[I] = V;
174}
175
Ted Kremenekf8fd4d42011-10-07 00:42:48 +0000176void CFGBlockValues::mergeIntoScratch(ValueVector const &source,
177 bool isFirst) {
178 if (isFirst)
179 scratch = source;
180 else
181 scratch |= source;
182}
183
Ted Kremeneka895fe92011-03-15 04:57:27 +0000184bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) {
Ted Kremenek6080d322012-07-19 04:59:05 +0000185 ValueVector &dst = getValueVector(block);
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000186 bool changed = (dst != scratch);
187 if (changed)
188 dst = scratch;
Richard Smith130b8d42012-07-13 23:33:44 +0000189#if DEBUG_LOGGING
Ted Kremenekba357292011-02-01 17:43:18 +0000190 printVector(block, scratch, 0);
191#endif
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000192 return changed;
193}
194
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000195void CFGBlockValues::resetScratch() {
196 scratch.reset();
197}
198
Ted Kremeneka895fe92011-03-15 04:57:27 +0000199ValueVector::reference CFGBlockValues::operator[](const VarDecl *vd) {
Ted Kremeneke3ae0a42011-03-15 05:30:12 +0000200 const llvm::Optional<unsigned> &idx = declToIndex.getValueIndex(vd);
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000201 assert(idx.hasValue());
202 return scratch[idx.getValue()];
203}
204
205//------------------------------------------------------------------------====//
206// Worklist: worklist for dataflow analysis.
207//====------------------------------------------------------------------------//
208
209namespace {
210class DataflowWorklist {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000211 SmallVector<const CFGBlock *, 20> worklist;
Ted Kremenek9b15c962011-03-15 04:57:32 +0000212 llvm::BitVector enqueuedBlocks;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000213public:
214 DataflowWorklist(const CFG &cfg) : enqueuedBlocks(cfg.getNumBlockIDs()) {}
215
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000216 void enqueueSuccessors(const CFGBlock *block);
217 const CFGBlock *dequeue();
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000218};
219}
220
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000221void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) {
Chandler Carrutha5328632011-07-08 11:19:06 +0000222 unsigned OldWorklistSize = worklist.size();
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000223 for (CFGBlock::const_succ_iterator I = block->succ_begin(),
224 E = block->succ_end(); I != E; ++I) {
Chandler Carrutha5328632011-07-08 11:19:06 +0000225 const CFGBlock *Successor = *I;
226 if (!Successor || enqueuedBlocks[Successor->getBlockID()])
227 continue;
228 worklist.push_back(Successor);
229 enqueuedBlocks[Successor->getBlockID()] = true;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000230 }
Chandler Carrutha5328632011-07-08 11:19:06 +0000231 if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
232 return;
233
234 // Rotate the newly added blocks to the start of the worklist so that it forms
235 // a proper queue when we pop off the end of the worklist.
236 std::rotate(worklist.begin(), worklist.begin() + OldWorklistSize,
237 worklist.end());
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000238}
239
240const CFGBlock *DataflowWorklist::dequeue() {
241 if (worklist.empty())
242 return 0;
243 const CFGBlock *b = worklist.back();
244 worklist.pop_back();
245 enqueuedBlocks[b->getBlockID()] = false;
246 return b;
247}
248
249//------------------------------------------------------------------------====//
Richard Smith6376d1f2012-07-17 00:06:14 +0000250// Classification of DeclRefExprs as use or initialization.
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000251//====------------------------------------------------------------------------//
252
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000253namespace {
254class FindVarResult {
255 const VarDecl *vd;
256 const DeclRefExpr *dr;
257public:
Richard Smith6376d1f2012-07-17 00:06:14 +0000258 FindVarResult(const VarDecl *vd, const DeclRefExpr *dr) : vd(vd), dr(dr) {}
259
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000260 const DeclRefExpr *getDeclRefExpr() const { return dr; }
261 const VarDecl *getDecl() const { return vd; }
262};
Richard Smith6376d1f2012-07-17 00:06:14 +0000263
264static const Expr *stripCasts(ASTContext &C, const Expr *Ex) {
265 while (Ex) {
266 Ex = Ex->IgnoreParenNoopCasts(C);
267 if (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
268 if (CE->getCastKind() == CK_LValueBitCast) {
269 Ex = CE->getSubExpr();
270 continue;
271 }
272 }
273 break;
274 }
275 return Ex;
276}
277
278/// If E is an expression comprising a reference to a single variable, find that
279/// variable.
280static FindVarResult findVar(const Expr *E, const DeclContext *DC) {
281 if (const DeclRefExpr *DRE =
282 dyn_cast<DeclRefExpr>(stripCasts(DC->getParentASTContext(), E)))
283 if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
284 if (isTrackedVar(VD, DC))
285 return FindVarResult(VD, DRE);
286 return FindVarResult(0, 0);
287}
288
289/// \brief Classify each DeclRefExpr as an initialization or a use. Any
290/// DeclRefExpr which isn't explicitly classified will be assumed to have
291/// escaped the analysis and will be treated as an initialization.
292class ClassifyRefs : public StmtVisitor<ClassifyRefs> {
293public:
294 enum Class {
295 Init,
296 Use,
297 SelfInit,
298 Ignore
299 };
300
301private:
302 const DeclContext *DC;
303 llvm::DenseMap<const DeclRefExpr*, Class> Classification;
304
305 bool isTrackedVar(const VarDecl *VD) const {
306 return ::isTrackedVar(VD, DC);
307 }
308
309 void classify(const Expr *E, Class C);
310
311public:
312 ClassifyRefs(AnalysisDeclContext &AC) : DC(cast<DeclContext>(AC.getDecl())) {}
313
314 void VisitDeclStmt(DeclStmt *DS);
315 void VisitUnaryOperator(UnaryOperator *UO);
316 void VisitBinaryOperator(BinaryOperator *BO);
317 void VisitCallExpr(CallExpr *CE);
318 void VisitCastExpr(CastExpr *CE);
319
320 void operator()(Stmt *S) { Visit(S); }
321
322 Class get(const DeclRefExpr *DRE) const {
323 llvm::DenseMap<const DeclRefExpr*, Class>::const_iterator I
324 = Classification.find(DRE);
325 if (I != Classification.end())
326 return I->second;
327
328 const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
329 if (!VD || !isTrackedVar(VD))
330 return Ignore;
331
332 return Init;
333 }
334};
335}
336
337static const DeclRefExpr *getSelfInitExpr(VarDecl *VD) {
338 if (Expr *Init = VD->getInit()) {
339 const DeclRefExpr *DRE
340 = dyn_cast<DeclRefExpr>(stripCasts(VD->getASTContext(), Init));
341 if (DRE && DRE->getDecl() == VD)
342 return DRE;
343 }
344 return 0;
345}
346
347void ClassifyRefs::classify(const Expr *E, Class C) {
348 FindVarResult Var = findVar(E, DC);
349 if (const DeclRefExpr *DRE = Var.getDeclRefExpr())
350 Classification[DRE] = std::max(Classification[DRE], C);
351}
352
353void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) {
354 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
355 DI != DE; ++DI) {
356 VarDecl *VD = dyn_cast<VarDecl>(*DI);
357 if (VD && isTrackedVar(VD))
358 if (const DeclRefExpr *DRE = getSelfInitExpr(VD))
359 Classification[DRE] = SelfInit;
360 }
361}
362
363void ClassifyRefs::VisitBinaryOperator(BinaryOperator *BO) {
364 // Ignore the evaluation of a DeclRefExpr on the LHS of an assignment. If this
365 // is not a compound-assignment, we will treat it as initializing the variable
366 // when TransferFunctions visits it. A compound-assignment does not affect
367 // whether a variable is uninitialized, and there's no point counting it as a
368 // use.
Richard Smithb21dd022012-07-17 01:27:33 +0000369 if (BO->isCompoundAssignmentOp())
370 classify(BO->getLHS(), Use);
371 else if (BO->getOpcode() == BO_Assign)
Richard Smith6376d1f2012-07-17 00:06:14 +0000372 classify(BO->getLHS(), Ignore);
373}
374
375void ClassifyRefs::VisitUnaryOperator(UnaryOperator *UO) {
376 // Increment and decrement are uses despite there being no lvalue-to-rvalue
377 // conversion.
378 if (UO->isIncrementDecrementOp())
379 classify(UO->getSubExpr(), Use);
380}
381
382void ClassifyRefs::VisitCallExpr(CallExpr *CE) {
383 // If a value is passed by const reference to a function, we should not assume
384 // that it is initialized by the call, and we conservatively do not assume
385 // that it is used.
386 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
387 I != E; ++I)
388 if ((*I)->getType().isConstQualified() && (*I)->isGLValue())
389 classify(*I, Ignore);
390}
391
392void ClassifyRefs::VisitCastExpr(CastExpr *CE) {
393 if (CE->getCastKind() == CK_LValueToRValue)
394 classify(CE->getSubExpr(), Use);
395 else if (CStyleCastExpr *CSE = dyn_cast<CStyleCastExpr>(CE)) {
396 if (CSE->getType()->isVoidType()) {
397 // Squelch any detected load of an uninitialized value if
398 // we cast it to void.
399 // e.g. (void) x;
400 classify(CSE->getSubExpr(), Ignore);
401 }
402 }
403}
404
405//------------------------------------------------------------------------====//
406// Transfer function for uninitialized values analysis.
407//====------------------------------------------------------------------------//
408
409namespace {
Ted Kremenek9e100ea2011-07-19 14:18:48 +0000410class TransferFunctions : public StmtVisitor<TransferFunctions> {
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000411 CFGBlockValues &vals;
412 const CFG &cfg;
Richard Smith4323bf82012-05-25 02:17:09 +0000413 const CFGBlock *block;
Ted Kremenek81ce1c82011-10-24 01:32:45 +0000414 AnalysisDeclContext &ac;
Richard Smith6376d1f2012-07-17 00:06:14 +0000415 const ClassifyRefs &classification;
Ted Kremenekedf22ed2012-09-13 00:21:35 +0000416 ObjCNoReturn objCNoRet;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000417 UninitVariablesHandler *handler;
Richard Smith6376d1f2012-07-17 00:06:14 +0000418
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000419public:
420 TransferFunctions(CFGBlockValues &vals, const CFG &cfg,
Richard Smith4323bf82012-05-25 02:17:09 +0000421 const CFGBlock *block, AnalysisDeclContext &ac,
Richard Smith6376d1f2012-07-17 00:06:14 +0000422 const ClassifyRefs &classification,
Ted Kremenekaed46772011-09-02 19:39:26 +0000423 UninitVariablesHandler *handler)
Richard Smith6376d1f2012-07-17 00:06:14 +0000424 : vals(vals), cfg(cfg), block(block), ac(ac),
Ted Kremenekedf22ed2012-09-13 00:21:35 +0000425 classification(classification), objCNoRet(ac.getASTContext()),
426 handler(handler) {}
Richard Smith6376d1f2012-07-17 00:06:14 +0000427
Richard Smith3d31e8b2012-05-24 23:45:35 +0000428 void reportUse(const Expr *ex, const VarDecl *vd);
Ted Kremenekbcf848f2011-01-25 19:13:48 +0000429
Ted Kremenekedf22ed2012-09-13 00:21:35 +0000430 void VisitBinaryOperator(BinaryOperator *bo);
Ted Kremenekbcf848f2011-01-25 19:13:48 +0000431 void VisitBlockExpr(BlockExpr *be);
Richard Smithb721e302012-07-02 23:23:04 +0000432 void VisitCallExpr(CallExpr *ce);
Ted Kremenekb63931e2011-01-18 21:18:58 +0000433 void VisitDeclRefExpr(DeclRefExpr *dr);
Ted Kremenekedf22ed2012-09-13 00:21:35 +0000434 void VisitDeclStmt(DeclStmt *ds);
435 void VisitObjCForCollectionStmt(ObjCForCollectionStmt *FS);
436 void VisitObjCMessageExpr(ObjCMessageExpr *ME);
Richard Smith4323bf82012-05-25 02:17:09 +0000437
Ted Kremenek93a31382011-01-27 02:29:34 +0000438 bool isTrackedVar(const VarDecl *vd) {
439 return ::isTrackedVar(vd, cast<DeclContext>(ac.getDecl()));
440 }
Richard Smith4323bf82012-05-25 02:17:09 +0000441
Richard Smith6376d1f2012-07-17 00:06:14 +0000442 FindVarResult findVar(const Expr *ex) {
443 return ::findVar(ex, cast<DeclContext>(ac.getDecl()));
444 }
445
Richard Smith4323bf82012-05-25 02:17:09 +0000446 UninitUse getUninitUse(const Expr *ex, const VarDecl *vd, Value v) {
447 UninitUse Use(ex, isAlwaysUninit(v));
448
449 assert(isUninitialized(v));
450 if (Use.getKind() == UninitUse::Always)
451 return Use;
452
453 // If an edge which leads unconditionally to this use did not initialize
454 // the variable, we can say something stronger than 'may be uninitialized':
455 // we can say 'either it's used uninitialized or you have dead code'.
456 //
457 // We track the number of successors of a node which have been visited, and
458 // visit a node once we have visited all of its successors. Only edges where
459 // the variable might still be uninitialized are followed. Since a variable
460 // can't transfer from being initialized to being uninitialized, this will
461 // trace out the subgraph which inevitably leads to the use and does not
462 // initialize the variable. We do not want to skip past loops, since their
463 // non-termination might be correlated with the initialization condition.
464 //
465 // For example:
466 //
467 // void f(bool a, bool b) {
468 // block1: int n;
469 // if (a) {
470 // block2: if (b)
471 // block3: n = 1;
472 // block4: } else if (b) {
473 // block5: while (!a) {
474 // block6: do_work(&a);
475 // n = 2;
476 // }
477 // }
478 // block7: if (a)
479 // block8: g();
480 // block9: return n;
481 // }
482 //
483 // Starting from the maybe-uninitialized use in block 9:
484 // * Block 7 is not visited because we have only visited one of its two
485 // successors.
486 // * Block 8 is visited because we've visited its only successor.
487 // From block 8:
488 // * Block 7 is visited because we've now visited both of its successors.
489 // From block 7:
490 // * Blocks 1, 2, 4, 5, and 6 are not visited because we didn't visit all
491 // of their successors (we didn't visit 4, 3, 5, 6, and 5, respectively).
492 // * Block 3 is not visited because it initializes 'n'.
493 // Now the algorithm terminates, having visited blocks 7 and 8, and having
494 // found the frontier is blocks 2, 4, and 5.
495 //
496 // 'n' is definitely uninitialized for two edges into block 7 (from blocks 2
497 // and 4), so we report that any time either of those edges is taken (in
498 // each case when 'b == false'), 'n' is used uninitialized.
499 llvm::SmallVector<const CFGBlock*, 32> Queue;
500 llvm::SmallVector<unsigned, 32> SuccsVisited(cfg.getNumBlockIDs(), 0);
501 Queue.push_back(block);
502 // Specify that we've already visited all successors of the starting block.
503 // This has the dual purpose of ensuring we never add it to the queue, and
504 // of marking it as not being a candidate element of the frontier.
505 SuccsVisited[block->getBlockID()] = block->succ_size();
506 while (!Queue.empty()) {
507 const CFGBlock *B = Queue.back();
508 Queue.pop_back();
509 for (CFGBlock::const_pred_iterator I = B->pred_begin(), E = B->pred_end();
510 I != E; ++I) {
511 const CFGBlock *Pred = *I;
512 if (vals.getValue(Pred, B, vd) == Initialized)
513 // This block initializes the variable.
514 continue;
515
Richard Smith130b8d42012-07-13 23:33:44 +0000516 unsigned &SV = SuccsVisited[Pred->getBlockID()];
517 if (!SV) {
518 // When visiting the first successor of a block, mark all NULL
519 // successors as having been visited.
520 for (CFGBlock::const_succ_iterator SI = Pred->succ_begin(),
521 SE = Pred->succ_end();
522 SI != SE; ++SI)
523 if (!*SI)
524 ++SV;
525 }
526
527 if (++SV == Pred->succ_size())
Richard Smith4323bf82012-05-25 02:17:09 +0000528 // All paths from this block lead to the use and don't initialize the
529 // variable.
530 Queue.push_back(Pred);
531 }
532 }
533
534 // Scan the frontier, looking for blocks where the variable was
535 // uninitialized.
536 for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) {
537 const CFGBlock *Block = *BI;
538 unsigned BlockID = Block->getBlockID();
539 const Stmt *Term = Block->getTerminator();
540 if (SuccsVisited[BlockID] && SuccsVisited[BlockID] < Block->succ_size() &&
541 Term) {
542 // This block inevitably leads to the use. If we have an edge from here
543 // to a post-dominator block, and the variable is uninitialized on that
544 // edge, we have found a bug.
545 for (CFGBlock::const_succ_iterator I = Block->succ_begin(),
546 E = Block->succ_end(); I != E; ++I) {
547 const CFGBlock *Succ = *I;
548 if (Succ && SuccsVisited[Succ->getBlockID()] >= Succ->succ_size() &&
549 vals.getValue(Block, Succ, vd) == Uninitialized) {
550 // Switch cases are a special case: report the label to the caller
551 // as the 'terminator', not the switch statement itself. Suppress
552 // situations where no label matched: we can't be sure that's
553 // possible.
554 if (isa<SwitchStmt>(Term)) {
555 const Stmt *Label = Succ->getLabel();
556 if (!Label || !isa<SwitchCase>(Label))
557 // Might not be possible.
558 continue;
559 UninitUse::Branch Branch;
560 Branch.Terminator = Label;
561 Branch.Output = 0; // Ignored.
562 Use.addUninitBranch(Branch);
563 } else {
564 UninitUse::Branch Branch;
565 Branch.Terminator = Term;
566 Branch.Output = I - Block->succ_begin();
567 Use.addUninitBranch(Branch);
568 }
569 }
570 }
571 }
572 }
573
574 return Use;
575 }
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000576};
577}
578
Richard Smith3d31e8b2012-05-24 23:45:35 +0000579void TransferFunctions::reportUse(const Expr *ex, const VarDecl *vd) {
580 if (!handler)
581 return;
582 Value v = vals[vd];
583 if (isUninitialized(v))
Richard Smith4323bf82012-05-25 02:17:09 +0000584 handler->handleUseOfUninitVariable(vd, getUninitUse(ex, vd, v));
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000585}
586
Richard Smith6376d1f2012-07-17 00:06:14 +0000587void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *FS) {
Ted Kremenek4058d872011-01-27 02:01:31 +0000588 // This represents an initialization of the 'element' value.
Richard Smith6376d1f2012-07-17 00:06:14 +0000589 if (DeclStmt *DS = dyn_cast<DeclStmt>(FS->getElement())) {
590 const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
591 if (isTrackedVar(VD))
592 vals[VD] = Initialized;
Ted Kremenek4058d872011-01-27 02:01:31 +0000593 }
Ted Kremenek4058d872011-01-27 02:01:31 +0000594}
595
Ted Kremenekbcf848f2011-01-25 19:13:48 +0000596void TransferFunctions::VisitBlockExpr(BlockExpr *be) {
Ted Kremenek77361762011-03-31 22:32:41 +0000597 const BlockDecl *bd = be->getBlockDecl();
598 for (BlockDecl::capture_const_iterator i = bd->capture_begin(),
599 e = bd->capture_end() ; i != e; ++i) {
600 const VarDecl *vd = i->getVariable();
Ted Kremenek77361762011-03-31 22:32:41 +0000601 if (!isTrackedVar(vd))
602 continue;
603 if (i->isByRef()) {
604 vals[vd] = Initialized;
605 continue;
606 }
Richard Smith3d31e8b2012-05-24 23:45:35 +0000607 reportUse(be, vd);
Ted Kremenekbcf848f2011-01-25 19:13:48 +0000608 }
609}
610
Richard Smithb721e302012-07-02 23:23:04 +0000611void TransferFunctions::VisitCallExpr(CallExpr *ce) {
Ted Kremenek7979ccf2012-09-12 05:53:43 +0000612 if (Decl *Callee = ce->getCalleeDecl()) {
613 if (Callee->hasAttr<ReturnsTwiceAttr>()) {
614 // After a call to a function like setjmp or vfork, any variable which is
615 // initialized anywhere within this function may now be initialized. For
616 // now, just assume such a call initializes all variables. FIXME: Only
617 // mark variables as initialized if they have an initializer which is
618 // reachable from here.
619 vals.setAllScratchValues(Initialized);
620 }
621 else if (Callee->hasAttr<AnalyzerNoReturnAttr>()) {
622 // Functions labeled like "analyzer_noreturn" are often used to denote
623 // "panic" functions that in special debug situations can still return,
624 // but for the most part should not be treated as returning. This is a
625 // useful annotation borrowed from the static analyzer that is useful for
626 // suppressing branch-specific false positives when we call one of these
627 // functions but keep pretending the path continues (when in reality the
628 // user doesn't care).
629 vals.setAllScratchValues(Unknown);
630 }
631 }
Richard Smithb721e302012-07-02 23:23:04 +0000632}
633
Ted Kremenek9e100ea2011-07-19 14:18:48 +0000634void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) {
Richard Smith6376d1f2012-07-17 00:06:14 +0000635 switch (classification.get(dr)) {
636 case ClassifyRefs::Ignore:
637 break;
638 case ClassifyRefs::Use:
639 reportUse(dr, cast<VarDecl>(dr->getDecl()));
640 break;
641 case ClassifyRefs::Init:
642 vals[cast<VarDecl>(dr->getDecl())] = Initialized;
643 break;
644 case ClassifyRefs::SelfInit:
645 if (handler)
646 handler->handleSelfInit(cast<VarDecl>(dr->getDecl()));
647 break;
648 }
Ted Kremenek9e100ea2011-07-19 14:18:48 +0000649}
650
Richard Smith6376d1f2012-07-17 00:06:14 +0000651void TransferFunctions::VisitBinaryOperator(BinaryOperator *BO) {
652 if (BO->getOpcode() == BO_Assign) {
653 FindVarResult Var = findVar(BO->getLHS());
654 if (const VarDecl *VD = Var.getDecl())
655 vals[VD] = Initialized;
656 }
657}
658
659void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
660 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000661 DI != DE; ++DI) {
Richard Smith6376d1f2012-07-17 00:06:14 +0000662 VarDecl *VD = dyn_cast<VarDecl>(*DI);
663 if (VD && isTrackedVar(VD)) {
664 if (getSelfInitExpr(VD)) {
665 // If the initializer consists solely of a reference to itself, we
666 // explicitly mark the variable as uninitialized. This allows code
667 // like the following:
668 //
669 // int x = x;
670 //
671 // to deliberately leave a variable uninitialized. Different analysis
672 // clients can detect this pattern and adjust their reporting
673 // appropriately, but we need to continue to analyze subsequent uses
674 // of the variable.
675 vals[VD] = Uninitialized;
676 } else if (VD->getInit()) {
677 // Treat the new variable as initialized.
678 vals[VD] = Initialized;
679 } else {
680 // No initializer: the variable is now uninitialized. This matters
681 // for cases like:
682 // while (...) {
683 // int n;
684 // use(n);
685 // n = 0;
686 // }
687 // FIXME: Mark the variable as uninitialized whenever its scope is
688 // left, since its scope could be re-entered by a jump over the
689 // declaration.
690 vals[VD] = Uninitialized;
Ted Kremenekb63931e2011-01-18 21:18:58 +0000691 }
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000692 }
693 }
694}
695
Ted Kremenekedf22ed2012-09-13 00:21:35 +0000696void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) {
697 // If the Objective-C message expression is an implicit no-return that
698 // is not modeled in the CFG, set the tracked dataflow values to Unknown.
699 if (objCNoRet.isImplicitNoReturn(ME)) {
700 vals.setAllScratchValues(Unknown);
701 }
702}
703
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000704//------------------------------------------------------------------------====//
705// High-level "driver" logic for uninitialized values analysis.
706//====------------------------------------------------------------------------//
707
Ted Kremenekb82ddd62011-01-20 17:37:17 +0000708static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
Ted Kremenek81ce1c82011-10-24 01:32:45 +0000709 AnalysisDeclContext &ac, CFGBlockValues &vals,
Richard Smith6376d1f2012-07-17 00:06:14 +0000710 const ClassifyRefs &classification,
Ted Kremenek352a7082011-04-04 20:30:58 +0000711 llvm::BitVector &wasAnalyzed,
Ted Kremenekaed46772011-09-02 19:39:26 +0000712 UninitVariablesHandler *handler = 0) {
Ted Kremenek352a7082011-04-04 20:30:58 +0000713 wasAnalyzed[block->getBlockID()] = true;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000714 vals.resetScratch();
Ted Kremenek6080d322012-07-19 04:59:05 +0000715 // Merge in values of predecessor blocks.
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000716 bool isFirst = true;
717 for (CFGBlock::const_pred_iterator I = block->pred_begin(),
718 E = block->pred_end(); I != E; ++I) {
Ted Kremenekaed46772011-09-02 19:39:26 +0000719 const CFGBlock *pred = *I;
720 if (wasAnalyzed[pred->getBlockID()]) {
Ted Kremenek6080d322012-07-19 04:59:05 +0000721 vals.mergeIntoScratch(vals.getValueVector(pred), isFirst);
Ted Kremenekaed46772011-09-02 19:39:26 +0000722 isFirst = false;
723 }
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000724 }
725 // Apply the transfer function.
Richard Smith6376d1f2012-07-17 00:06:14 +0000726 TransferFunctions tf(vals, cfg, block, ac, classification, handler);
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000727 for (CFGBlock::const_iterator I = block->begin(), E = block->end();
728 I != E; ++I) {
729 if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) {
Ted Kremenekadfb4452011-08-23 23:05:04 +0000730 tf.Visit(const_cast<Stmt*>(cs->getStmt()));
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000731 }
732 }
Ted Kremeneka895fe92011-03-15 04:57:27 +0000733 return vals.updateValueVectorWithScratch(block);
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000734}
735
Chandler Carruthb4836ea2011-07-06 16:21:37 +0000736void clang::runUninitializedVariablesAnalysis(
737 const DeclContext &dc,
738 const CFG &cfg,
Ted Kremenek81ce1c82011-10-24 01:32:45 +0000739 AnalysisDeclContext &ac,
Chandler Carruthb4836ea2011-07-06 16:21:37 +0000740 UninitVariablesHandler &handler,
741 UninitVariablesAnalysisStats &stats) {
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000742 CFGBlockValues vals(cfg);
743 vals.computeSetOfDeclarations(dc);
744 if (vals.hasNoDeclarations())
745 return;
Ted Kremenek37881932011-04-04 23:29:12 +0000746
Chandler Carruthb4836ea2011-07-06 16:21:37 +0000747 stats.NumVariablesAnalyzed = vals.getNumEntries();
748
Richard Smith6376d1f2012-07-17 00:06:14 +0000749 // Precompute which expressions are uses and which are initializations.
750 ClassifyRefs classification(ac);
751 cfg.VisitBlockStmts(classification);
752
Ted Kremenek37881932011-04-04 23:29:12 +0000753 // Mark all variables uninitialized at the entry.
754 const CFGBlock &entry = cfg.getEntry();
Ted Kremenek6080d322012-07-19 04:59:05 +0000755 ValueVector &vec = vals.getValueVector(&entry);
756 const unsigned n = vals.getNumEntries();
757 for (unsigned j = 0; j < n ; ++j) {
758 vec[j] = Uninitialized;
Ted Kremenek37881932011-04-04 23:29:12 +0000759 }
760
761 // Proceed with the workist.
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000762 DataflowWorklist worklist(cfg);
Ted Kremenek9b15c962011-03-15 04:57:32 +0000763 llvm::BitVector previouslyVisited(cfg.getNumBlockIDs());
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000764 worklist.enqueueSuccessors(&cfg.getEntry());
Ted Kremenek352a7082011-04-04 20:30:58 +0000765 llvm::BitVector wasAnalyzed(cfg.getNumBlockIDs(), false);
Ted Kremenekaed46772011-09-02 19:39:26 +0000766 wasAnalyzed[cfg.getEntry().getBlockID()] = true;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000767
768 while (const CFGBlock *block = worklist.dequeue()) {
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000769 // Did the block change?
Richard Smith6376d1f2012-07-17 00:06:14 +0000770 bool changed = runOnBlock(block, cfg, ac, vals,
771 classification, wasAnalyzed);
Chandler Carruthb4836ea2011-07-06 16:21:37 +0000772 ++stats.NumBlockVisits;
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000773 if (changed || !previouslyVisited[block->getBlockID()])
774 worklist.enqueueSuccessors(block);
775 previouslyVisited[block->getBlockID()] = true;
776 }
777
778 // Run through the blocks one more time, and report uninitialized variabes.
779 for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) {
Ted Kremenekaed46772011-09-02 19:39:26 +0000780 const CFGBlock *block = *BI;
781 if (wasAnalyzed[block->getBlockID()]) {
Richard Smith6376d1f2012-07-17 00:06:14 +0000782 runOnBlock(block, cfg, ac, vals, classification, wasAnalyzed, &handler);
Chandler Carruthb4836ea2011-07-06 16:21:37 +0000783 ++stats.NumBlockVisits;
784 }
Ted Kremenekb749a6d2011-01-15 02:58:47 +0000785 }
786}
787
788UninitVariablesHandler::~UninitVariablesHandler() {}