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 &ac;
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