UninitializedValues.cpp revision b831c673621c5587642343cace9def134916a17b
16f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek//==- UninitializedValues.cpp - Find Uninitialized Values -------*- C++ --*-==// 2610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 3610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// The LLVM Compiler Infrastructure 4610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 5610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// This file is distributed under the University of Illinois Open Source 6610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// License. See LICENSE.TXT for details. 7610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 8610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 9610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 10610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// This file implements uninitialized values analysis for source-level CFGs. 11610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// 12610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//===----------------------------------------------------------------------===// 13610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 1413bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek#include <utility> 15610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "llvm/ADT/Optional.h" 16610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "llvm/ADT/SmallVector.h" 17610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "llvm/ADT/BitVector.h" 18610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "llvm/ADT/DenseMap.h" 19610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "clang/AST/Decl.h" 20610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "clang/Analysis/CFG.h" 21a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek#include "clang/Analysis/AnalysisContext.h" 22610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" 236f34213f8d6ae8c77685b53664527e39bfaaca3bTed Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h" 24c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h" 25610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 26610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekusing namespace clang; 27610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 2840900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenekstatic bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) { 291cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() && 301cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek vd->getDeclContext() == dc) { 311cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek QualType ty = vd->getType(); 321cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek return ty->isScalarType() || ty->isVectorType(); 331cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek } 341cbc31515e9b979f55178ffd4587e8671f7ebbfaTed Kremenek return false; 35c104e53639de4424b83955acfadc977773b5883dTed Kremenek} 36c104e53639de4424b83955acfadc977773b5883dTed Kremenek 37610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//------------------------------------------------------------------------====// 38136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek// DeclToIndex: a mapping from Decls we track to value indices. 39610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//====------------------------------------------------------------------------// 40610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 41610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 42136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekclass DeclToIndex { 43610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek llvm::DenseMap<const VarDecl *, unsigned> map; 44610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 45136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek DeclToIndex() {} 46610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 47610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek /// Compute the actual mapping from declarations to bits. 48610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void computeMap(const DeclContext &dc); 49610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 50610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek /// Return the number of declarations in the map. 51610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek unsigned size() const { return map.size(); } 52610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 53610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek /// Returns the bit vector index for a given declaration. 54b831c673621c5587642343cace9def134916a17bTed Kremenek llvm::Optional<unsigned> getValueIndex(const VarDecl *d) const; 55610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 56610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 57610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 58136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekvoid DeclToIndex::computeMap(const DeclContext &dc) { 59610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek unsigned count = 0; 60610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek DeclContext::specific_decl_iterator<VarDecl> I(dc.decls_begin()), 61610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek E(dc.decls_end()); 62610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for ( ; I != E; ++I) { 63610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const VarDecl *vd = *I; 6440900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek if (isTrackedVar(vd, &dc)) 65610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek map[vd] = count++; 66610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 67610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 68610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 69b831c673621c5587642343cace9def134916a17bTed Kremenekllvm::Optional<unsigned> DeclToIndex::getValueIndex(const VarDecl *d) const { 70b831c673621c5587642343cace9def134916a17bTed Kremenek llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I = map.find(d); 71610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (I == map.end()) 72610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return llvm::Optional<unsigned>(); 73610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return I->second; 74610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 75610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 76610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//------------------------------------------------------------------------====// 77610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// CFGBlockValues: dataflow values for CFG blocks. 78610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//====------------------------------------------------------------------------// 79610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 80f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek// These values are defined in such a way that a merge can be done using 81f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek// a bitwise OR. 82f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenekenum Value { Unknown = 0x0, /* 00 */ 83f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek Initialized = 0x1, /* 01 */ 84f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek Uninitialized = 0x2, /* 10 */ 85f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek MayUninitialized = 0x3 /* 11 */ }; 86f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek 87f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenekstatic bool isUninitialized(const Value v) { 88f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek return v >= Uninitialized; 89f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek} 90f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenekstatic bool isAlwaysUninit(const Value v) { 91f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek return v == Uninitialized; 92f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek} 93afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek 94da57f3eeab7b7f7f6e6788956f0a0d9adf196a7dBenjamin Kramernamespace { 95afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenekclass ValueVector { 96afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek llvm::BitVector vec; 97afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenekpublic: 98afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek ValueVector() {} 99f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek ValueVector(unsigned size) : vec(size << 1) {} 100f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek void resize(unsigned n) { vec.resize(n << 1); } 101afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek void merge(const ValueVector &rhs) { vec |= rhs.vec; } 102afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek bool operator!=(const ValueVector &rhs) const { return vec != rhs.vec; } 103afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek void reset() { vec.reset(); } 104496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek 105496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek class reference { 106496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek ValueVector &vv; 107496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek const unsigned idx; 108496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek 109496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek reference(); // Undefined 110496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek public: 111496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek reference(ValueVector &vv, unsigned idx) : vv(vv), idx(idx) {} 112496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek ~reference() {} 113496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek 114496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek reference &operator=(Value v) { 115f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek vv.vec[idx << 1] = (((unsigned) v) & 0x1) ? true : false; 116f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek vv.vec[(idx << 1) | 1] = (((unsigned) v) & 0x2) ? true : false; 117496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek return *this; 118496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek } 119f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek operator Value() { 120f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek unsigned x = (vv.vec[idx << 1] ? 1 : 0) | (vv.vec[(idx << 1) | 1] ? 2 :0); 121f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek return (Value) x; 122f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek } 123496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek }; 124496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek 125496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek reference operator[](unsigned idx) { return reference(*this, idx); } 126afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek}; 127afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek 128136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenektypedef std::pair<ValueVector *, ValueVector *> BVPair; 12913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 130610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass CFGBlockValues { 131610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFG &cfg; 13213bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek BVPair *vals; 133136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector scratch; 1344ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek DeclToIndex declToIndex; 13513bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 136136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector &lazyCreate(ValueVector *&bv); 137610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 138610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek CFGBlockValues(const CFG &cfg); 139610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek ~CFGBlockValues(); 140610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 141610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void computeSetOfDeclarations(const DeclContext &dc); 142136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector &getValueVector(const CFGBlock *block, 14313bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek const CFGBlock *dstBlock); 14413bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 145136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek BVPair &getValueVectors(const CFGBlock *block, bool shouldLazyCreate); 14613bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 147136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek void mergeIntoScratch(ValueVector const &source, bool isFirst); 148136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek bool updateValueVectorWithScratch(const CFGBlock *block); 149136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek bool updateValueVectors(const CFGBlock *block, const BVPair &newVals); 150610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 151610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek bool hasNoDeclarations() const { 1524ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek return declToIndex.size() == 0; 153610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 154610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 155b831c673621c5587642343cace9def134916a17bTed Kremenek bool hasEntry(const VarDecl *vd) const { 156b831c673621c5587642343cace9def134916a17bTed Kremenek return declToIndex.getValueIndex(vd).hasValue(); 157b831c673621c5587642343cace9def134916a17bTed Kremenek } 158b831c673621c5587642343cace9def134916a17bTed Kremenek 159610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void resetScratch(); 160136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector &getScratch() { return scratch; } 16113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 162136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector::reference operator[](const VarDecl *vd); 163610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 164da57f3eeab7b7f7f6e6788956f0a0d9adf196a7dBenjamin Kramer} // end anonymous namespace 165610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 166610068c8cd2321f90e147b12cf794e1f840b6405Ted KremenekCFGBlockValues::CFGBlockValues(const CFG &c) : cfg(c), vals(0) { 167610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek unsigned n = cfg.getNumBlockIDs(); 168610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (!n) 169610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return; 170136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek vals = new std::pair<ValueVector*, ValueVector*>[n]; 1712d78c374508dc1f4595fe5172b39bf51b07aa48cFrancois Pichet memset(vals, 0, sizeof(*vals) * n); 172610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 173610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 174610068c8cd2321f90e147b12cf794e1f840b6405Ted KremenekCFGBlockValues::~CFGBlockValues() { 175610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek unsigned n = cfg.getNumBlockIDs(); 176610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (n == 0) 177610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return; 17813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek for (unsigned i = 0; i < n; ++i) { 17913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek delete vals[i].first; 18013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek delete vals[i].second; 18113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek } 182610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek delete [] vals; 183610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 184610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 185610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) { 1864ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek declToIndex.computeMap(dc); 1874ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek scratch.resize(declToIndex.size()); 188610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 189610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 190136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted KremenekValueVector &CFGBlockValues::lazyCreate(ValueVector *&bv) { 19113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek if (!bv) 1924ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek bv = new ValueVector(declToIndex.size()); 193610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return *bv; 194610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 195610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 19613bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek/// This function pattern matches for a '&&' or '||' that appears at 19713bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek/// the beginning of a CFGBlock that also (1) has a terminator and 19813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek/// (2) has no other elements. If such an expression is found, it is returned. 19913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenekstatic BinaryOperator *getLogicalOperatorInChain(const CFGBlock *block) { 20013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek if (block->empty()) 20113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek return 0; 2029fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 2033c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const CFGStmt *cstmt = block->front().getAs<CFGStmt>(); 20476709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek if (!cstmt) 20576709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek return 0; 20676709bf816e5e1b70b859bb607cf3ee91db12b76Ted Kremenek 2073c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek BinaryOperator *b = llvm::dyn_cast_or_null<BinaryOperator>(cstmt->getStmt()); 2089fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 2099fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (!b || !b->isLogicalOp()) 21013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek return 0; 2119fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 2129fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (block->pred_size() == 2 && 2139fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek ((block->succ_size() == 2 && block->getTerminatorCondition() == b) || 2149fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek block->size() == 1)) 2159fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek return b; 2169fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 2179fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek return 0; 21813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek} 21913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 220136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted KremenekValueVector &CFGBlockValues::getValueVector(const CFGBlock *block, 221136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek const CFGBlock *dstBlock) { 22213bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek unsigned idx = block->getBlockID(); 2239fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (dstBlock && getLogicalOperatorInChain(block)) { 2249fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (*block->succ_begin() == dstBlock) 2259fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek return lazyCreate(vals[idx].first); 2269fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek assert(*(block->succ_begin()+1) == dstBlock); 2279fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek return lazyCreate(vals[idx].second); 22813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek } 22913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 23013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek assert(vals[idx].second == 0); 23113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek return lazyCreate(vals[idx].first); 23213bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek} 23313bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 234136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted KremenekBVPair &CFGBlockValues::getValueVectors(const clang::CFGBlock *block, 235136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek bool shouldLazyCreate) { 23613bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek unsigned idx = block->getBlockID(); 23713bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek lazyCreate(vals[idx].first); 2389fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (shouldLazyCreate) 2399fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek lazyCreate(vals[idx].second); 24013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek return vals[idx]; 24113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek} 24213bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 243136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekvoid CFGBlockValues::mergeIntoScratch(ValueVector const &source, 244610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek bool isFirst) { 245610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (isFirst) 246610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek scratch = source; 247610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek else 248afb10c4bda2ac2c268fa7e6c11141584f57de119Ted Kremenek scratch.merge(source); 249610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 2509fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#if 0 251136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekstatic void printVector(const CFGBlock *block, ValueVector &bv, 2529fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek unsigned num) { 2539fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 2549fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek llvm::errs() << block->getBlockID() << " :"; 2559fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek for (unsigned i = 0; i < bv.size(); ++i) { 2569fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek llvm::errs() << ' ' << bv[i]; 2579fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek } 2589fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek llvm::errs() << " : " << num << '\n'; 2599fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek} 2609fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#endif 261610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 262136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekbool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { 263136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek ValueVector &dst = getValueVector(block, 0); 264610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek bool changed = (dst != scratch); 265610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (changed) 266610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek dst = scratch; 2679fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#if 0 2689fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek printVector(block, scratch, 0); 2699fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#endif 27013bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek return changed; 27113bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek} 27213bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 273136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenekbool CFGBlockValues::updateValueVectors(const CFGBlock *block, 27413bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek const BVPair &newVals) { 275136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek BVPair &vals = getValueVectors(block, true); 27613bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek bool changed = *newVals.first != *vals.first || 27713bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek *newVals.second != *vals.second; 27813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek *vals.first = *newVals.first; 27913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek *vals.second = *newVals.second; 2809fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#if 0 2819fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek printVector(block, *vals.first, 1); 2829fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek printVector(block, *vals.second, 2); 2839fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek#endif 284610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return changed; 285610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 286610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 287610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid CFGBlockValues::resetScratch() { 288610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek scratch.reset(); 289610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 290610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 291136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted KremenekValueVector::reference CFGBlockValues::operator[](const VarDecl *vd) { 2924ddb3871307376d27d0f276c9da0ecce0384f01fTed Kremenek const llvm::Optional<unsigned> &idx = declToIndex.getValueIndex(vd); 293610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek assert(idx.hasValue()); 294610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return scratch[idx.getValue()]; 295610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 296610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 297610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//------------------------------------------------------------------------====// 298610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// Worklist: worklist for dataflow analysis. 299610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//====------------------------------------------------------------------------// 300610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 301610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 302610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass DataflowWorklist { 303610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek llvm::SmallVector<const CFGBlock *, 20> worklist; 304496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek llvm::BitVector enqueuedBlocks; 305610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 306610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek DataflowWorklist(const CFG &cfg) : enqueuedBlocks(cfg.getNumBlockIDs()) {} 307610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 308610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void enqueue(const CFGBlock *block); 309610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void enqueueSuccessors(const CFGBlock *block); 310610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFGBlock *dequeue(); 311610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 312610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 313610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 314610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 315610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid DataflowWorklist::enqueue(const CFGBlock *block) { 316c104e53639de4424b83955acfadc977773b5883dTed Kremenek if (!block) 317c104e53639de4424b83955acfadc977773b5883dTed Kremenek return; 318610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek unsigned idx = block->getBlockID(); 319610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (enqueuedBlocks[idx]) 320610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return; 321610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek worklist.push_back(block); 322610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek enqueuedBlocks[idx] = true; 323610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 324610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 325610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) { 326610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for (CFGBlock::const_succ_iterator I = block->succ_begin(), 327610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek E = block->succ_end(); I != E; ++I) { 328610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek enqueue(*I); 329610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 330610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 331610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 332610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekconst CFGBlock *DataflowWorklist::dequeue() { 333610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (worklist.empty()) 334610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return 0; 335610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFGBlock *b = worklist.back(); 336610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek worklist.pop_back(); 337610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek enqueuedBlocks[b->getBlockID()] = false; 338610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return b; 339610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 340610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 341610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//------------------------------------------------------------------------====// 342610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// Transfer function for uninitialized values analysis. 343610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//====------------------------------------------------------------------------// 344610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 345610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremeneknamespace { 346610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass FindVarResult { 347610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const VarDecl *vd; 348610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const DeclRefExpr *dr; 349610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 350610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek FindVarResult(VarDecl *vd, DeclRefExpr *dr) : vd(vd), dr(dr) {} 351610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 352610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const DeclRefExpr *getDeclRefExpr() const { return dr; } 353610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const VarDecl *getDecl() const { return vd; } 354610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 355610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 356610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekclass TransferFunctions : public CFGRecStmtVisitor<TransferFunctions> { 357610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek CFGBlockValues &vals; 358610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFG &cfg; 359a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek AnalysisContext ∾ 360610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek UninitVariablesHandler *handler; 361c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek const DeclRefExpr *currentDR; 362dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek const Expr *currentVoidCast; 363a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek const bool flagBlockUses; 364610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekpublic: 365610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek TransferFunctions(CFGBlockValues &vals, const CFG &cfg, 366a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek AnalysisContext &ac, 367a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek UninitVariablesHandler *handler, 368a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek bool flagBlockUses) 369a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek : vals(vals), cfg(cfg), ac(ac), handler(handler), currentDR(0), 370dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek currentVoidCast(0), flagBlockUses(flagBlockUses) {} 371610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 372610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFG &getCFG() { return cfg; } 373f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek void reportUninit(const DeclRefExpr *ex, const VarDecl *vd, 374f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek bool isAlwaysUninit); 375a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek 376a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek void VisitBlockExpr(BlockExpr *be); 377610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void VisitDeclStmt(DeclStmt *ds); 378c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek void VisitDeclRefExpr(DeclRefExpr *dr); 379610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void VisitUnaryOperator(UnaryOperator *uo); 380610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void VisitBinaryOperator(BinaryOperator *bo); 381610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek void VisitCastExpr(CastExpr *ce); 382f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *se); 3831ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *fs); 38440900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek 38540900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek bool isTrackedVar(const VarDecl *vd) { 386b831c673621c5587642343cace9def134916a17bTed Kremenek#if 1 387b831c673621c5587642343cace9def134916a17bTed Kremenek // FIXME: This is a temporary workaround to deal with the fact 388b831c673621c5587642343cace9def134916a17bTed Kremenek // that DeclContext's do not always contain all of their variables! 389b831c673621c5587642343cace9def134916a17bTed Kremenek return vals.hasEntry(vd); 390b831c673621c5587642343cace9def134916a17bTed Kremenek#else 39140900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek return ::isTrackedVar(vd, cast<DeclContext>(ac.getDecl())); 392b831c673621c5587642343cace9def134916a17bTed Kremenek#endif 39340900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek } 39440900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek 39540900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek FindVarResult findBlockVarDecl(Expr *ex); 396610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek}; 397610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 398610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 399610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid TransferFunctions::reportUninit(const DeclRefExpr *ex, 400f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek const VarDecl *vd, bool isAlwaysUnit) { 401f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (handler) handler->handleUseOfUninitVariable(ex, vd, isAlwaysUnit); 402610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 403610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 40440900ee8f3072d05456134b57c0fad85a6bb21a6Ted KremenekFindVarResult TransferFunctions::findBlockVarDecl(Expr* ex) { 4051ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (DeclRefExpr* dr = dyn_cast<DeclRefExpr>(ex->IgnoreParenCasts())) 4061ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (VarDecl *vd = dyn_cast<VarDecl>(dr->getDecl())) 4071ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (isTrackedVar(vd)) 40840900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek return FindVarResult(vd, dr); 4091ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek return FindVarResult(0, 0); 4101ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek} 4111ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 4121ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenekvoid TransferFunctions::BlockStmt_VisitObjCForCollectionStmt( 4131ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek ObjCForCollectionStmt *fs) { 4141ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 4151ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek Visit(fs->getCollection()); 4161ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 4171ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek // This represents an initialization of the 'element' value. 4181ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek Stmt *element = fs->getElement(); 4191ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek const VarDecl* vd = 0; 4201ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 4211ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (DeclStmt* ds = dyn_cast<DeclStmt>(element)) { 4221ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek vd = cast<VarDecl>(ds->getSingleDecl()); 4231ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (!isTrackedVar(vd)) 4241ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek vd = 0; 4251ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek } 4261ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek else { 4271ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek // Initialize the value of the reference variable. 4281ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek const FindVarResult &res = findBlockVarDecl(cast<Expr>(element)); 4291ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek vd = res.getDecl(); 4301ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (!vd) { 4311ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek Visit(element); 4321ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek return; 4331ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek } 4341ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek } 4351ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 4361ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek if (vd) 4371ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek vals[vd] = Initialized; 4381ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek} 4391ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28dTed Kremenek 440a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenekvoid TransferFunctions::VisitBlockExpr(BlockExpr *be) { 441a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek if (!flagBlockUses || !handler) 442a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek return; 443a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek AnalysisContext::referenced_decls_iterator i, e; 444a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek llvm::tie(i, e) = ac.getReferencedBlockVars(be->getBlockDecl()); 445a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek for ( ; i != e; ++i) { 446a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek const VarDecl *vd = *i; 44740900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek if (vd->getAttr<BlocksAttr>() || !vd->hasLocalStorage() || 44840900ee8f3072d05456134b57c0fad85a6bb21a6Ted Kremenek !isTrackedVar(vd)) 449a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek continue; 450f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek Value v = vals[vd]; 451f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (isUninitialized(v)) 452f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek handler->handleUseOfUninitVariable(be, vd, isAlwaysUninit(v)); 453a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek } 454a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek} 455a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek 456610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid TransferFunctions::VisitDeclStmt(DeclStmt *ds) { 457610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for (DeclStmt::decl_iterator DI = ds->decl_begin(), DE = ds->decl_end(); 458610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek DI != DE; ++DI) { 459610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (VarDecl *vd = dyn_cast<VarDecl>(*DI)) { 4604dccb90e92ba9e4abffe0177493b6db9949678ddTed Kremenek if (isTrackedVar(vd)) { 4614dccb90e92ba9e4abffe0177493b6db9949678ddTed Kremenek vals[vd] = Uninitialized; 462610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (Stmt *init = vd->getInit()) { 463610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek Visit(init); 464c104e53639de4424b83955acfadc977773b5883dTed Kremenek vals[vd] = Initialized; 465610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 4664dccb90e92ba9e4abffe0177493b6db9949678ddTed Kremenek } 467c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek else if (Stmt *init = vd->getInit()) { 468c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(init); 469c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek } 470610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 471610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 472610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 473610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 474c21fed361c11f13db345cba69101578578d8fb79Ted Kremenekvoid TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) { 475c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // We assume that DeclRefExprs wrapped in an lvalue-to-rvalue cast 476c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // cannot be block-level expressions. Therefore, we determine if 477c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // a DeclRefExpr is involved in a "load" by comparing it to the current 478c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // DeclRefExpr found when analyzing the last lvalue-to-rvalue CastExpr. 479c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // If a DeclRefExpr is not involved in a load, we are essentially computing 480c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // its address, either for assignment to a reference or via the '&' operator. 481c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // In such cases, treat the variable as being initialized, since this 482c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // analysis isn't powerful enough to do alias tracking. 483c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek if (dr != currentDR) 484c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek if (const VarDecl *vd = dyn_cast<VarDecl>(dr->getDecl())) 485c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek if (isTrackedVar(vd)) 486c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek vals[vd] = Initialized; 487c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek} 488c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek 489610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid TransferFunctions::VisitBinaryOperator(clang::BinaryOperator *bo) { 490610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (bo->isAssignmentOp()) { 491610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const FindVarResult &res = findBlockVarDecl(bo->getLHS()); 492610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (const VarDecl* vd = res.getDecl()) { 493c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // We assume that DeclRefExprs wrapped in a BinaryOperator "assignment" 494c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // cannot be block-level expressions. Therefore, we determine if 495c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // a DeclRefExpr is involved in a "load" by comparing it to the current 496c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // DeclRefExpr found when analyzing the last lvalue-to-rvalue CastExpr. 497c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek SaveAndRestore<const DeclRefExpr*> lastDR(currentDR, 498c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek res.getDeclRefExpr()); 499c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(bo->getRHS()); 500c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(bo->getLHS()); 501c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek 502496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek ValueVector::reference val = vals[vd]; 503f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (isUninitialized(val)) { 504610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (bo->getOpcode() != BO_Assign) 505f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val)); 506496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek val = Initialized; 507610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 508c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek return; 509610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 510610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 511c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(bo->getRHS()); 512c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(bo->getLHS()); 513610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 514610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 515610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid TransferFunctions::VisitUnaryOperator(clang::UnaryOperator *uo) { 516610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek switch (uo->getOpcode()) { 517610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek case clang::UO_PostDec: 518610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek case clang::UO_PostInc: 519610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek case clang::UO_PreDec: 520610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek case clang::UO_PreInc: { 521610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const FindVarResult &res = findBlockVarDecl(uo->getSubExpr()); 522610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (const VarDecl *vd = res.getDecl()) { 523c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // We assume that DeclRefExprs wrapped in a unary operator ++/-- 524c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // cannot be block-level expressions. Therefore, we determine if 525c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // a DeclRefExpr is involved in a "load" by comparing it to the current 526c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // DeclRefExpr found when analyzing the last lvalue-to-rvalue CastExpr. 527c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek SaveAndRestore<const DeclRefExpr*> lastDR(currentDR, 528c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek res.getDeclRefExpr()); 529c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(uo->getSubExpr()); 530c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek 531f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek ValueVector::reference val = vals[vd]; 532f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (isUninitialized(val)) { 533f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val)); 534f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek // Don't cascade warnings. 535f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek val = Initialized; 536610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 537c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek return; 538610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 539610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek break; 540610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 541610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek default: 542610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek break; 543610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 544c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(uo->getSubExpr()); 545610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 546610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 547610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid TransferFunctions::VisitCastExpr(clang::CastExpr *ce) { 548610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (ce->getCastKind() == CK_LValueToRValue) { 549610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const FindVarResult &res = findBlockVarDecl(ce->getSubExpr()); 550c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek if (const VarDecl *vd = res.getDecl()) { 551c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // We assume that DeclRefExprs wrapped in an lvalue-to-rvalue cast 552c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // cannot be block-level expressions. Therefore, we determine if 553c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // a DeclRefExpr is involved in a "load" by comparing it to the current 554c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // DeclRefExpr found when analyzing the last lvalue-to-rvalue CastExpr. 555c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // Here we update 'currentDR' to be the one associated with this 556c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // lvalue-to-rvalue cast. Then, when we analyze the DeclRefExpr, we 557c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // will know that we are not computing its lvalue for other purposes 558c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek // than to perform a load. 559c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek SaveAndRestore<const DeclRefExpr*> lastDR(currentDR, 560c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek res.getDeclRefExpr()); 561c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(ce->getSubExpr()); 562f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (currentVoidCast != ce) { 563f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek Value val = vals[vd]; 564f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek if (isUninitialized(val)) { 565f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val)); 566f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek // Don't cascade warnings. 567f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek vals[vd] = Initialized; 568f7bafc77ba12bb1beb665243a0334cd81e024728Ted Kremenek } 569c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek } 570c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek return; 571c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek } 572dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek } 573dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek else if (CStyleCastExpr *cse = dyn_cast<CStyleCastExpr>(ce)) { 574dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek if (cse->getType()->isVoidType()) { 575dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek // e.g. (void) x; 576dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek SaveAndRestore<const Expr *> 577dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek lastVoidCast(currentVoidCast, cse->getSubExpr()->IgnoreParens()); 578dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek Visit(cse->getSubExpr()); 579dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek return; 580dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek } 581dd0f7942c5415ce146dcc02d57fc503c683f8625Ted Kremenek } 582c21fed361c11f13db345cba69101578578d8fb79Ted Kremenek Visit(ce->getSubExpr()); 583610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 584610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 585f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbournevoid TransferFunctions::VisitUnaryExprOrTypeTraitExpr( 586f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne UnaryExprOrTypeTraitExpr *se) { 587f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (se->getKind() == UETT_SizeOf) { 5889660803cd332d5c605899435019bb3b37fca3accTed Kremenek if (se->getType()->isConstantSizeType()) 5899660803cd332d5c605899435019bb3b37fca3accTed Kremenek return; 5909660803cd332d5c605899435019bb3b37fca3accTed Kremenek // Handle VLAs. 5919660803cd332d5c605899435019bb3b37fca3accTed Kremenek Visit(se->getArgumentExpr()); 5929660803cd332d5c605899435019bb3b37fca3accTed Kremenek } 5939660803cd332d5c605899435019bb3b37fca3accTed Kremenek} 5949660803cd332d5c605899435019bb3b37fca3accTed Kremenek 595610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//------------------------------------------------------------------------====// 596610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek// High-level "driver" logic for uninitialized values analysis. 597610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek//====------------------------------------------------------------------------// 598610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 59913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenekstatic bool runOnBlock(const CFGBlock *block, const CFG &cfg, 600a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek AnalysisContext &ac, CFGBlockValues &vals, 601a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek UninitVariablesHandler *handler = 0, 602a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek bool flagBlockUses = false) { 60313bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 60413bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek if (const BinaryOperator *b = getLogicalOperatorInChain(block)) { 6059fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek CFGBlock::const_pred_iterator itr = block->pred_begin(); 606136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek BVPair vA = vals.getValueVectors(*itr, false); 6079fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek ++itr; 608136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek BVPair vB = vals.getValueVectors(*itr, false); 6099fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 6109fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek BVPair valsAB; 6119fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek 6129fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek if (b->getOpcode() == BO_LAnd) { 6139fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek // Merge the 'F' bits from the first and second. 6149fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek vals.mergeIntoScratch(*(vA.second ? vA.second : vA.first), true); 6159fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek vals.mergeIntoScratch(*(vB.second ? vB.second : vB.first), false); 6169fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek valsAB.first = vA.first; 6172d4bed140f65d713673d2d32ec3adadc960078c6Ted Kremenek valsAB.second = &vals.getScratch(); 61813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek } 6199fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek else { 6209fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek // Merge the 'T' bits from the first and second. 6219fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek assert(b->getOpcode() == BO_LOr); 6229fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek vals.mergeIntoScratch(*vA.first, true); 6239fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek vals.mergeIntoScratch(*vB.first, false); 6249fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek valsAB.first = &vals.getScratch(); 6259fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek valsAB.second = vA.second ? vA.second : vA.first; 6269fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek } 627136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek return vals.updateValueVectors(block, valsAB); 62813bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek } 62913bd4236ab8297350be388ab442b4c42eb8fe437Ted Kremenek 6309fcbceed43e5610fdff43defe533934733453ae2Ted Kremenek // Default behavior: merge in values of predecessor blocks. 631610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek vals.resetScratch(); 632610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek bool isFirst = true; 633610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for (CFGBlock::const_pred_iterator I = block->pred_begin(), 634610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek E = block->pred_end(); I != E; ++I) { 635136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek vals.mergeIntoScratch(vals.getValueVector(*I, block), isFirst); 636610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek isFirst = false; 637610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 638610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek // Apply the transfer function. 639a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek TransferFunctions tf(vals, cfg, ac, handler, flagBlockUses); 640610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for (CFGBlock::const_iterator I = block->begin(), E = block->end(); 641610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek I != E; ++I) { 642610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) { 643610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek tf.BlockStmt_Visit(cs->getStmt()); 644610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 645610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 646136f8f24b0b6c0e57aaa4375d280d72dc5492615Ted Kremenek return vals.updateValueVectorWithScratch(block); 647610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 648610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 649610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenekvoid clang::runUninitializedVariablesAnalysis(const DeclContext &dc, 650610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek const CFG &cfg, 651a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek AnalysisContext &ac, 652610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek UninitVariablesHandler &handler) { 653610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek CFGBlockValues vals(cfg); 654610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek vals.computeSetOfDeclarations(dc); 655610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (vals.hasNoDeclarations()) 656610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek return; 657610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek DataflowWorklist worklist(cfg); 658496398d523de712ac1084c53a397ca3987fe43dbTed Kremenek llvm::BitVector previouslyVisited(cfg.getNumBlockIDs()); 659610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 660610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek worklist.enqueueSuccessors(&cfg.getEntry()); 661610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 662610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek while (const CFGBlock *block = worklist.dequeue()) { 663610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek // Did the block change? 664a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek bool changed = runOnBlock(block, cfg, ac, vals); 665610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek if (changed || !previouslyVisited[block->getBlockID()]) 666610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek worklist.enqueueSuccessors(block); 667610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek previouslyVisited[block->getBlockID()] = true; 668610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 669610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 670610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek // Run through the blocks one more time, and report uninitialized variabes. 671610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) { 672a8c17a5babab35f2db26bf218e7571d1af4afedfTed Kremenek runOnBlock(*BI, cfg, ac, vals, &handler, /* flagBlockUses */ true); 673610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek } 674610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek} 675610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 676610068c8cd2321f90e147b12cf794e1f840b6405Ted KremenekUninitVariablesHandler::~UninitVariablesHandler() {} 677610068c8cd2321f90e147b12cf794e1f840b6405Ted Kremenek 678