clang  14.0.0git
UninitializedObjectChecker.cpp
Go to the documentation of this file.
1 //===----- UninitializedObjectChecker.cpp ------------------------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a checker that reports uninitialized fields in objects
10 // created after a constructor call.
11 //
12 // To read about command line options and how the checker works, refer to the
13 // top of the file and inline comments in UninitializedObject.h.
14 //
15 // Some of the logic is implemented in UninitializedPointee.cpp, to reduce the
16 // complexity of this file.
17 //
18 //===----------------------------------------------------------------------===//
19 
21 #include "UninitializedObject.h"
28 
29 using namespace clang;
30 using namespace clang::ento;
31 using namespace clang::ast_matchers;
32 
33 /// We'll mark fields (and pointee of fields) that are confirmed to be
34 /// uninitialized as already analyzed.
35 REGISTER_SET_WITH_PROGRAMSTATE(AnalyzedRegions, const MemRegion *)
36 
37 namespace {
38 
39 class UninitializedObjectChecker
40  : public Checker<check::EndFunction, check::DeadSymbols> {
41  std::unique_ptr<BuiltinBug> BT_uninitField;
42 
43 public:
44  // The fields of this struct will be initialized when registering the checker.
46 
47  UninitializedObjectChecker()
48  : BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
49 
50  void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
51  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
52 };
53 
54 /// A basic field type, that is not a pointer or a reference, it's dynamic and
55 /// static type is the same.
56 class RegularField final : public FieldNode {
57 public:
58  RegularField(const FieldRegion *FR) : FieldNode(FR) {}
59 
60  virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
61  Out << "uninitialized field ";
62  }
63 
64  virtual void printPrefix(llvm::raw_ostream &Out) const override {}
65 
66  virtual void printNode(llvm::raw_ostream &Out) const override {
67  Out << getVariableName(getDecl());
68  }
69 
70  virtual void printSeparator(llvm::raw_ostream &Out) const override {
71  Out << '.';
72  }
73 };
74 
75 /// Represents that the FieldNode that comes after this is declared in a base
76 /// of the previous FieldNode. As such, this descendant doesn't wrap a
77 /// FieldRegion, and is purely a tool to describe a relation between two other
78 /// FieldRegion wrapping descendants.
79 class BaseClass final : public FieldNode {
80  const QualType BaseClassT;
81 
82 public:
83  BaseClass(const QualType &T) : FieldNode(nullptr), BaseClassT(T) {
84  assert(!T.isNull());
85  assert(T->getAsCXXRecordDecl());
86  }
87 
88  virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
89  llvm_unreachable("This node can never be the final node in the "
90  "fieldchain!");
91  }
92 
93  virtual void printPrefix(llvm::raw_ostream &Out) const override {}
94 
95  virtual void printNode(llvm::raw_ostream &Out) const override {
96  Out << BaseClassT->getAsCXXRecordDecl()->getName() << "::";
97  }
98 
99  virtual void printSeparator(llvm::raw_ostream &Out) const override {}
100 
101  virtual bool isBase() const override { return true; }
102 };
103 
104 } // end of anonymous namespace
105 
106 // Utility function declarations.
107 
108 /// Returns the region that was constructed by CtorDecl, or nullptr if that
109 /// isn't possible.
110 static const TypedValueRegion *
112  CheckerContext &Context);
113 
114 /// Checks whether the object constructed by \p Ctor will be analyzed later
115 /// (e.g. if the object is a field of another object, in which case we'd check
116 /// it multiple times).
117 static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
118  CheckerContext &Context);
119 
120 /// Checks whether RD contains a field with a name or type name that matches
121 /// \p Pattern.
122 static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern);
123 
124 /// Checks _syntactically_ whether it is possible to access FD from the record
125 /// that contains it without a preceding assert (even if that access happens
126 /// inside a method). This is mainly used for records that act like unions, like
127 /// having multiple bit fields, with only a fraction being properly initialized.
128 /// If these fields are properly guarded with asserts, this method returns
129 /// false.
130 ///
131 /// Since this check is done syntactically, this method could be inaccurate.
132 static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State);
133 
134 //===----------------------------------------------------------------------===//
135 // Methods for UninitializedObjectChecker.
136 //===----------------------------------------------------------------------===//
137 
138 void UninitializedObjectChecker::checkEndFunction(
139  const ReturnStmt *RS, CheckerContext &Context) const {
140 
141  const auto *CtorDecl = dyn_cast_or_null<CXXConstructorDecl>(
142  Context.getLocationContext()->getDecl());
143  if (!CtorDecl)
144  return;
145 
146  if (!CtorDecl->isUserProvided())
147  return;
148 
149  if (CtorDecl->getParent()->isUnion())
150  return;
151 
152  // This avoids essentially the same error being reported multiple times.
153  if (willObjectBeAnalyzedLater(CtorDecl, Context))
154  return;
155 
156  const TypedValueRegion *R = getConstructedRegion(CtorDecl, Context);
157  if (!R)
158  return;
159 
160  FindUninitializedFields F(Context.getState(), R, Opts);
161 
162  std::pair<ProgramStateRef, const UninitFieldMap &> UninitInfo =
163  F.getResults();
164 
165  ProgramStateRef UpdatedState = UninitInfo.first;
166  const UninitFieldMap &UninitFields = UninitInfo.second;
167 
168  if (UninitFields.empty()) {
169  Context.addTransition(UpdatedState);
170  return;
171  }
172 
173  // There are uninitialized fields in the record.
174 
175  ExplodedNode *Node = Context.generateNonFatalErrorNode(UpdatedState);
176  if (!Node)
177  return;
178 
179  PathDiagnosticLocation LocUsedForUniqueing;
180  const Stmt *CallSite = Context.getStackFrame()->getCallSite();
181  if (CallSite)
182  LocUsedForUniqueing = PathDiagnosticLocation::createBegin(
183  CallSite, Context.getSourceManager(), Node->getLocationContext());
184 
185  // For Plist consumers that don't support notes just yet, we'll convert notes
186  // to warnings.
187  if (Opts.ShouldConvertNotesToWarnings) {
188  for (const auto &Pair : UninitFields) {
189 
190  auto Report = std::make_unique<PathSensitiveBugReport>(
191  *BT_uninitField, Pair.second, Node, LocUsedForUniqueing,
192  Node->getLocationContext()->getDecl());
193  Context.emitReport(std::move(Report));
194  }
195  return;
196  }
197 
198  SmallString<100> WarningBuf;
199  llvm::raw_svector_ostream WarningOS(WarningBuf);
200  WarningOS << UninitFields.size() << " uninitialized field"
201  << (UninitFields.size() == 1 ? "" : "s")
202  << " at the end of the constructor call";
203 
204  auto Report = std::make_unique<PathSensitiveBugReport>(
205  *BT_uninitField, WarningOS.str(), Node, LocUsedForUniqueing,
206  Node->getLocationContext()->getDecl());
207 
208  for (const auto &Pair : UninitFields) {
209  Report->addNote(Pair.second,
210  PathDiagnosticLocation::create(Pair.first->getDecl(),
211  Context.getSourceManager()));
212  }
213  Context.emitReport(std::move(Report));
214 }
215 
216 void UninitializedObjectChecker::checkDeadSymbols(SymbolReaper &SR,
217  CheckerContext &C) const {
218  ProgramStateRef State = C.getState();
219  for (const MemRegion *R : State->get<AnalyzedRegions>()) {
220  if (!SR.isLiveRegion(R))
221  State = State->remove<AnalyzedRegions>(R);
222  }
223 }
224 
225 //===----------------------------------------------------------------------===//
226 // Methods for FindUninitializedFields.
227 //===----------------------------------------------------------------------===//
228 
230  ProgramStateRef State, const TypedValueRegion *const R,
231  const UninitObjCheckerOptions &Opts)
232  : State(State), ObjectR(R), Opts(Opts) {
233 
234  isNonUnionUninit(ObjectR, FieldChainInfo(ChainFactory));
235 
236  // In non-pedantic mode, if ObjectR doesn't contain a single initialized
237  // field, we'll assume that Object was intentionally left uninitialized.
238  if (!Opts.IsPedantic && !isAnyFieldInitialized())
239  UninitFields.clear();
240 }
241 
242 bool FindUninitializedFields::addFieldToUninits(FieldChainInfo Chain,
243  const MemRegion *PointeeR) {
244  const FieldRegion *FR = Chain.getUninitRegion();
245 
246  assert((PointeeR || !isDereferencableType(FR->getDecl()->getType())) &&
247  "One must also pass the pointee region as a parameter for "
248  "dereferenceable fields!");
249 
250  if (State->getStateManager().getContext().getSourceManager().isInSystemHeader(
251  FR->getDecl()->getLocation()))
252  return false;
253 
254  if (Opts.IgnoreGuardedFields && !hasUnguardedAccess(FR->getDecl(), State))
255  return false;
256 
257  if (State->contains<AnalyzedRegions>(FR))
258  return false;
259 
260  if (PointeeR) {
261  if (State->contains<AnalyzedRegions>(PointeeR)) {
262  return false;
263  }
264  State = State->add<AnalyzedRegions>(PointeeR);
265  }
266 
267  State = State->add<AnalyzedRegions>(FR);
268 
269  UninitFieldMap::mapped_type NoteMsgBuf;
270  llvm::raw_svector_ostream OS(NoteMsgBuf);
271  Chain.printNoteMsg(OS);
272 
273  return UninitFields.insert({FR, std::move(NoteMsgBuf)}).second;
274 }
275 
276 bool FindUninitializedFields::isNonUnionUninit(const TypedValueRegion *R,
277  FieldChainInfo LocalChain) {
278  assert(R->getValueType()->isRecordType() &&
279  !R->getValueType()->isUnionType() &&
280  "This method only checks non-union record objects!");
281 
282  const RecordDecl *RD = R->getValueType()->getAsRecordDecl()->getDefinition();
283 
284  if (!RD) {
285  IsAnyFieldInitialized = true;
286  return true;
287  }
288 
289  if (!Opts.IgnoredRecordsWithFieldPattern.empty() &&
291  IsAnyFieldInitialized = true;
292  return false;
293  }
294 
295  bool ContainsUninitField = false;
296 
297  // Are all of this non-union's fields initialized?
298  for (const FieldDecl *I : RD->fields()) {
299 
300  const auto FieldVal =
301  State->getLValue(I, loc::MemRegionVal(R)).castAs<loc::MemRegionVal>();
302  const auto *FR = FieldVal.getRegionAs<FieldRegion>();
303  QualType T = I->getType();
304 
305  // If LocalChain already contains FR, then we encountered a cyclic
306  // reference. In this case, region FR is already under checking at an
307  // earlier node in the directed tree.
308  if (LocalChain.contains(FR))
309  return false;
310 
311  if (T->isStructureOrClassType()) {
312  if (isNonUnionUninit(FR, LocalChain.add(RegularField(FR))))
313  ContainsUninitField = true;
314  continue;
315  }
316 
317  if (T->isUnionType()) {
318  if (isUnionUninit(FR)) {
319  if (addFieldToUninits(LocalChain.add(RegularField(FR))))
320  ContainsUninitField = true;
321  } else
322  IsAnyFieldInitialized = true;
323  continue;
324  }
325 
326  if (T->isArrayType()) {
327  IsAnyFieldInitialized = true;
328  continue;
329  }
330 
331  SVal V = State->getSVal(FieldVal);
332 
333  if (isDereferencableType(T) || V.getAs<nonloc::LocAsInteger>()) {
334  if (isDereferencableUninit(FR, LocalChain))
335  ContainsUninitField = true;
336  continue;
337  }
338 
339  if (isPrimitiveType(T)) {
340  if (isPrimitiveUninit(V)) {
341  if (addFieldToUninits(LocalChain.add(RegularField(FR))))
342  ContainsUninitField = true;
343  }
344  continue;
345  }
346 
347  llvm_unreachable("All cases are handled!");
348  }
349 
350  // Checking bases. The checker will regard inherited data members as direct
351  // fields.
352  const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
353  if (!CXXRD)
354  return ContainsUninitField;
355 
356  for (const CXXBaseSpecifier &BaseSpec : CXXRD->bases()) {
357  const auto *BaseRegion = State->getLValue(BaseSpec, R)
358  .castAs<loc::MemRegionVal>()
359  .getRegionAs<TypedValueRegion>();
360 
361  // If the head of the list is also a BaseClass, we'll overwrite it to avoid
362  // note messages like 'this->A::B::x'.
363  if (!LocalChain.isEmpty() && LocalChain.getHead().isBase()) {
364  if (isNonUnionUninit(BaseRegion, LocalChain.replaceHead(
365  BaseClass(BaseSpec.getType()))))
366  ContainsUninitField = true;
367  } else {
368  if (isNonUnionUninit(BaseRegion,
369  LocalChain.add(BaseClass(BaseSpec.getType()))))
370  ContainsUninitField = true;
371  }
372  }
373 
374  return ContainsUninitField;
375 }
376 
377 bool FindUninitializedFields::isUnionUninit(const TypedValueRegion *R) {
378  assert(R->getValueType()->isUnionType() &&
379  "This method only checks union objects!");
380  // TODO: Implement support for union fields.
381  return false;
382 }
383 
384 bool FindUninitializedFields::isPrimitiveUninit(const SVal &V) {
385  if (V.isUndef())
386  return true;
387 
388  IsAnyFieldInitialized = true;
389  return false;
390 }
391 
392 //===----------------------------------------------------------------------===//
393 // Methods for FieldChainInfo.
394 //===----------------------------------------------------------------------===//
395 
396 bool FieldChainInfo::contains(const FieldRegion *FR) const {
397  for (const FieldNode &Node : Chain) {
398  if (Node.isSameRegion(FR))
399  return true;
400  }
401  return false;
402 }
403 
404 /// Prints every element except the last to `Out`. Since ImmutableLists store
405 /// elements in reverse order, and have no reverse iterators, we use a
406 /// recursive function to print the fieldchain correctly. The last element in
407 /// the chain is to be printed by `FieldChainInfo::print`.
408 static void printTail(llvm::raw_ostream &Out,
410 
411 // FIXME: This function constructs an incorrect string in the following case:
412 //
413 // struct Base { int x; };
414 // struct D1 : Base {}; struct D2 : Base {};
415 //
416 // struct MostDerived : D1, D2 {
417 // MostDerived() {}
418 // }
419 //
420 // A call to MostDerived::MostDerived() will cause two notes that say
421 // "uninitialized field 'this->x'", but we can't refer to 'x' directly,
422 // we need an explicit namespace resolution whether the uninit field was
423 // 'D1::x' or 'D2::x'.
424 void FieldChainInfo::printNoteMsg(llvm::raw_ostream &Out) const {
425  if (Chain.isEmpty())
426  return;
427 
428  const FieldNode &LastField = getHead();
429 
430  LastField.printNoteMsg(Out);
431  Out << '\'';
432 
433  for (const FieldNode &Node : Chain)
434  Node.printPrefix(Out);
435 
436  Out << "this->";
437  printTail(Out, Chain.getTail());
438  LastField.printNode(Out);
439  Out << '\'';
440 }
441 
442 static void printTail(llvm::raw_ostream &Out,
443  const FieldChainInfo::FieldChain L) {
444  if (L.isEmpty())
445  return;
446 
447  printTail(Out, L.getTail());
448 
449  L.getHead().printNode(Out);
450  L.getHead().printSeparator(Out);
451 }
452 
453 //===----------------------------------------------------------------------===//
454 // Utility functions.
455 //===----------------------------------------------------------------------===//
456 
457 static const TypedValueRegion *
459  CheckerContext &Context) {
460 
461  Loc ThisLoc =
462  Context.getSValBuilder().getCXXThis(CtorDecl, Context.getStackFrame());
463 
464  SVal ObjectV = Context.getState()->getSVal(ThisLoc);
465 
466  auto *R = ObjectV.getAsRegion()->getAs<TypedValueRegion>();
467  if (R && !R->getValueType()->getAsCXXRecordDecl())
468  return nullptr;
469 
470  return R;
471 }
472 
474  CheckerContext &Context) {
475 
476  const TypedValueRegion *CurrRegion = getConstructedRegion(Ctor, Context);
477  if (!CurrRegion)
478  return false;
479 
480  const LocationContext *LC = Context.getLocationContext();
481  while ((LC = LC->getParent())) {
482 
483  // If \p Ctor was called by another constructor.
484  const auto *OtherCtor = dyn_cast<CXXConstructorDecl>(LC->getDecl());
485  if (!OtherCtor)
486  continue;
487 
488  const TypedValueRegion *OtherRegion =
489  getConstructedRegion(OtherCtor, Context);
490  if (!OtherRegion)
491  continue;
492 
493  // If the CurrRegion is a subregion of OtherRegion, it will be analyzed
494  // during the analysis of OtherRegion.
495  if (CurrRegion->isSubRegionOf(OtherRegion))
496  return true;
497  }
498 
499  return false;
500 }
501 
502 static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern) {
503  llvm::Regex R(Pattern);
504 
505  for (const FieldDecl *FD : RD->fields()) {
506  if (R.match(FD->getType().getAsString()))
507  return true;
508  if (R.match(FD->getName()))
509  return true;
510  }
511 
512  return false;
513 }
514 
515 static const Stmt *getMethodBody(const CXXMethodDecl *M) {
516  if (isa<CXXConstructorDecl>(M))
517  return nullptr;
518 
519  if (!M->isDefined())
520  return nullptr;
521 
522  return M->getDefinition()->getBody();
523 }
524 
526 
528  return true;
529 
530  const auto *Parent = dyn_cast<CXXRecordDecl>(FD->getParent());
531 
532  if (!Parent)
533  return true;
534 
535  Parent = Parent->getDefinition();
536  assert(Parent && "The record's definition must be avaible if an uninitialized"
537  " field of it was found!");
538 
539  ASTContext &AC = State->getStateManager().getContext();
540 
541  auto FieldAccessM = memberExpr(hasDeclaration(equalsNode(FD))).bind("access");
542 
543  auto AssertLikeM = callExpr(callee(functionDecl(
544  hasAnyName("exit", "panic", "error", "Assert", "assert", "ziperr",
545  "assfail", "db_error", "__assert", "__assert2", "_wassert",
546  "__assert_rtn", "__assert_fail", "dtrace_assfail",
547  "yy_fatal_error", "_XCAssertionFailureHandler",
548  "_DTAssertionFailureHandler", "_TSAssertionFailureHandler"))));
549 
550  auto NoReturnFuncM = callExpr(callee(functionDecl(isNoReturn())));
551 
552  auto GuardM =
553  stmt(anyOf(ifStmt(), switchStmt(), conditionalOperator(), AssertLikeM,
554  NoReturnFuncM))
555  .bind("guard");
556 
557  for (const CXXMethodDecl *M : Parent->methods()) {
558  const Stmt *MethodBody = getMethodBody(M);
559  if (!MethodBody)
560  continue;
561 
562  auto Accesses = match(stmt(hasDescendant(FieldAccessM)), *MethodBody, AC);
563  if (Accesses.empty())
564  continue;
565  const auto *FirstAccess = Accesses[0].getNodeAs<MemberExpr>("access");
566  assert(FirstAccess);
567 
568  auto Guards = match(stmt(hasDescendant(GuardM)), *MethodBody, AC);
569  if (Guards.empty())
570  return true;
571  const auto *FirstGuard = Guards[0].getNodeAs<Stmt>("guard");
572  assert(FirstGuard);
573 
574  if (FirstAccess->getBeginLoc() < FirstGuard->getBeginLoc())
575  return true;
576  }
577 
578  return false;
579 }
580 
582  // If Field is a captured lambda variable, Field->getName() will return with
583  // an empty string. We can however acquire it's name from the lambda's
584  // captures.
585  const auto *CXXParent = dyn_cast<CXXRecordDecl>(Field->getParent());
586 
587  if (CXXParent && CXXParent->isLambda()) {
588  assert(CXXParent->captures_begin());
589  auto It = CXXParent->captures_begin() + Field->getFieldIndex();
590 
591  if (It->capturesVariable())
592  return llvm::Twine("/*captured variable*/" +
593  It->getCapturedVar()->getName())
594  .str();
595 
596  if (It->capturesThis())
597  return "/*'this' capture*/";
598 
599  llvm_unreachable("No other capture type is expected!");
600  }
601 
602  return std::string(Field->getName());
603 }
604 
605 void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) {
606  auto Chk = Mgr.registerChecker<UninitializedObjectChecker>();
607 
608  const AnalyzerOptions &AnOpts = Mgr.getAnalyzerOptions();
609  UninitObjCheckerOptions &ChOpts = Chk->Opts;
610 
611  ChOpts.IsPedantic = AnOpts.getCheckerBooleanOption(Chk, "Pedantic");
612  ChOpts.ShouldConvertNotesToWarnings = AnOpts.getCheckerBooleanOption(
613  Chk, "NotesAsWarnings");
614  ChOpts.CheckPointeeInitialization = AnOpts.getCheckerBooleanOption(
615  Chk, "CheckPointeeInitialization");
617  std::string(AnOpts.getCheckerStringOption(Chk, "IgnoreRecordsWithField"));
618  ChOpts.IgnoreGuardedFields =
619  AnOpts.getCheckerBooleanOption(Chk, "IgnoreGuardedFields");
620 
621  std::string ErrorMsg;
622  if (!llvm::Regex(ChOpts.IgnoredRecordsWithFieldPattern).isValid(ErrorMsg))
623  Mgr.reportInvalidCheckerOptionValue(Chk, "IgnoreRecordsWithField",
624  "a valid regex, building failed with error message "
625  "\"" + ErrorMsg + "\"");
626 }
627 
628 bool ento::shouldRegisterUninitializedObjectChecker(const CheckerManager &mgr) {
629  return true;
630 }
hasUnguardedAccess
static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State)
Checks syntactically whether it is possible to access FD from the record that contains it without a p...
Definition: UninitializedObjectChecker.cpp:525
clang::Type::isRecordType
bool isRecordType() const
Definition: Type.h:6763
clang::ast_matchers::hasAnyName
const internal::VariadicFunction< internal::Matcher< NamedDecl >, StringRef, internal::hasAnyNameFunc > hasAnyName
Matches NamedDecl nodes that have any of the specified names.
Definition: ASTMatchersInternal.cpp:996
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2401
clang::ento::PathDiagnosticLocation
Definition: PathDiagnostic.h:197
willObjectBeAnalyzedLater
static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor, CheckerContext &Context)
Checks whether the object constructed by Ctor will be analyzed later (e.g.
Definition: UninitializedObjectChecker.cpp:473
UninitializedObject.h
clang::LocationContext
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Definition: AnalysisDeclContext.h:215
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:809
clang::ento::CheckerManager::registerChecker
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Definition: CheckerManager.h:205
clang::ento::SVal::getAsRegion
const MemRegion * getAsRegion() const
Definition: SVals.cpp:131
clang::ast_matchers::anyOf
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
Definition: ASTMatchersInternal.cpp:988
clang::ento::FieldNode::printNoteMsg
virtual void printNoteMsg(llvm::raw_ostream &Out) const =0
If this is the last element of the fieldchain, this method will print the note message associated wit...
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:54
clang::ento::CheckerManager::getAnalyzerOptions
const AnalyzerOptions & getAnalyzerOptions() const
Definition: CheckerManager.h:171
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2835
clang::ento::ExplodedNode
Definition: ExplodedGraph.h:65
clang::ento::FieldChainInfo::isEmpty
bool isEmpty() const
Definition: UninitializedObject.h:186
clang::ast_matchers::memberExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, MemberExpr > memberExpr
Matches member expressions.
Definition: ASTMatchersInternal.cpp:811
clang::ento::isPrimitiveType
bool isPrimitiveType(const QualType &T)
Returns true if T is a primitive type.
Definition: UninitializedObject.h:324
clang::ento::UninitObjCheckerOptions::IgnoreGuardedFields
bool IgnoreGuardedFields
Definition: UninitializedObject.h:78
clang::ento::FieldChainInfo::contains
bool contains(const FieldRegion *FR) const
Definition: UninitializedObjectChecker.cpp:396
clang::ento::FieldChainInfo::getHead
const FieldNode & getHead() const
Definition: UninitializedObject.h:188
clang::RecordDecl::getDefinition
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Definition: Decl.h:4064
clang::ento::SubRegion::isSubRegionOf
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:134
ASTMatchFinder.h
clang::ento
Definition: CocoaConventions.h:23
clang::ento::loc::MemRegionVal
Definition: SVals.h:606
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:695
clang::ento::FieldNode::isBase
virtual bool isBase() const
Definition: UninitializedObject.h:145
printTail
static void printTail(llvm::raw_ostream &Out, const FieldChainInfo::FieldChain L)
Prints every element except the last to Out.
Definition: UninitializedObjectChecker.cpp:442
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
clang::FunctionDecl::getDefinition
FunctionDecl * getDefinition()
Get the definition for this declaration.
Definition: Decl.h:2119
clang::ento::getVariableName
std::string getVariableName(const FieldDecl *Field)
Returns with Field's name.
Definition: UninitializedObjectChecker.cpp:581
V
#define V(N, I)
Definition: ASTContext.h:3121
printNode
static Error printNode(StringRef Id, const MatchFinder::MatchResult &Match, std::string *Result)
Definition: Stencil.cpp:47
clang::ento::UninitObjCheckerOptions::CheckPointeeInitialization
bool CheckPointeeInitialization
Definition: UninitializedObject.h:76
clang::ast_matchers
Definition: ASTMatchers.h:98
BuiltinCheckerRegistration.h
clang::Decl::getAccess
AccessSpecifier getAccess() const
Definition: DeclBase.h:478
Node
DynTypedNode Node
Definition: ASTMatchFinder.cpp:67
clang::ento::PathDiagnosticLocation::create
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
Definition: PathDiagnostic.h:250
clang::AS_public
@ AS_public
Definition: Specifiers.h:109
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::ast_matchers::switchStmt
const internal::VariadicDynCastAllOfMatcher< Stmt, SwitchStmt > switchStmt
Matches switch statements.
Definition: ASTMatchersInternal.cpp:906
clang::ento::BuiltinBug
Definition: BugType.h:69
DriverDiagnostic.h
clang::ento::isDereferencableType
bool isDereferencableType(const QualType &T)
Definition: UninitializedObject.h:330
clang::FunctionDecl::getBody
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:3035
llvm::SmallString
Definition: LLVM.h:37
REGISTER_SET_WITH_PROGRAMSTATE
#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set of type NameTy, suitable for placement into the ProgramState.
Definition: ProgramStateTrait.h:109
clang::ast_matchers::ifStmt
const internal::VariadicDynCastAllOfMatcher< Stmt, IfStmt > ifStmt
Matches if statements.
Definition: ASTMatchersInternal.cpp:893
clang::ento::FieldNode::printNode
virtual void printNode(llvm::raw_ostream &Out) const =0
Print the node. Should contain the name of the field stored in FR.
clang::ento::UninitObjCheckerOptions
Definition: UninitializedObject.h:73
clang::ento::SymbolReaper
A class responsible for cleaning up unused symbols.
Definition: SymbolManager.h:505
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1753
clang::ento::FieldRegion
Definition: MemRegion.h:1054
clang::ento::UninitObjCheckerOptions::IsPedantic
bool IsPedantic
Definition: UninitializedObject.h:74
getMethodBody
static const Stmt * getMethodBody(const CXXMethodDecl *M)
Definition: UninitializedObjectChecker.cpp:515
clang::ento::SymbolReaper::isLiveRegion
bool isLiveRegion(const MemRegion *region)
Definition: SymbolManager.cpp:408
clang::ento::FieldChainInfo::FieldChain
llvm::ImmutableList< const FieldNode & > FieldChain
Definition: UninitializedObject.h:162
clang::ento::Loc
Definition: SVals.h:327
clang::LocationContext::getParent
const LocationContext * getParent() const
Definition: AnalysisDeclContext.h:243
clang::ento::MemRegion::getAs
const RegionTy * getAs() const
Definition: MemRegion.h:1286
clang::ento::FindUninitializedFields::isAnyFieldInitialized
bool isAnyFieldInitialized()
Returns whether the analyzed region contains at least one initialized field.
Definition: UninitializedObject.h:235
clang::Type::isUnionType
bool isUnionType() const
Definition: Type.cpp:595
BugType.h
clang::RecordDecl::fields
field_range fields() const
Definition: Decl.h:4079
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:738
getConstructedRegion
static const TypedValueRegion * getConstructedRegion(const CXXConstructorDecl *CtorDecl, CheckerContext &Context)
Returns the region that was constructed by CtorDecl, or nullptr if that isn't possible.
Definition: UninitializedObjectChecker.cpp:458
clang::AnalyzerOptions
Stores options for the analyzer from the command line.
Definition: AnalyzerOptions.h:163
clang::Type::getAsRecordDecl
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1757
State
LineState State
Definition: UnwrappedLineFormatter.cpp:986
clang::ento::FieldChainInfo::getUninitRegion
const FieldRegion * getUninitRegion() const
Definition: UninitializedObject.h:189
clang::ast_matchers::hasDescendant
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
Definition: ASTMatchersInternal.cpp:1009
clang::ast_matchers::callExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
Definition: ASTMatchersInternal.cpp:816
clang::ento::CheckerManager::reportInvalidCheckerOptionValue
void reportInvalidCheckerOptionValue(const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) const
Emits an error through a DiagnosticsEngine about an invalid user supplied checker option value.
Definition: CheckerManager.cpp:62
CheckerContext.h
clang::ast_matchers::functionDecl
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
Definition: ASTMatchersInternal.cpp:805
Checker.h
clang::ento::FieldChainInfo::add
FieldChainInfo add(const FieldNodeT &FN)
Constructs a new FieldChainInfo object with FN appended.
Definition: UninitializedObject.h:337
clang::ento::TypedValueRegion::getValueType
virtual QualType getValueType() const =0
clang::ento::CheckerManager
Definition: CheckerManager.h:127
clang::FieldDecl::getParent
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition: Decl.h:3027
clang::ento::nonloc::LocAsInteger
Definition: SVals.h:417
clang::ento::FieldNode
A lightweight polymorphic wrapper around FieldRegion *.
Definition: UninitializedObject.h:85
clang
Definition: CalledOnceCheck.h:17
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::ast_matchers::match
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
Definition: ASTMatchFinder.h:312
clang::CXXBaseSpecifier
Represents a base class of a C++ class.
Definition: DeclCXX.h:147
clang::ento::PathDiagnosticLocation::createBegin
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Definition: PathDiagnostic.cpp:580
clang::ento::CheckerContext
Definition: CheckerContext.h:23
clang::ento::FieldRegion::getDecl
const FieldDecl * getDecl() const override
Definition: MemRegion.h:1070
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3162
clang::ento::Checker
Definition: Checker.h:517
clang::ento::FindUninitializedFields::FindUninitializedFields
FindUninitializedFields(ProgramStateRef State, const TypedValueRegion *const R, const UninitObjCheckerOptions &Opts)
Constructs the FindUninitializedField object, searches for and stores uninitialized fields in R.
Definition: UninitializedObjectChecker.cpp:229
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:75
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
clang::ento::FieldChainInfo::replaceHead
FieldChainInfo replaceHead(const FieldNodeT &FN)
Constructs a new FieldChainInfo object with FN as the new head of the list.
Definition: UninitializedObject.h:348
clang::ento::TypedValueRegion
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:522
clang::ento::UninitObjCheckerOptions::IgnoredRecordsWithFieldPattern
std::string IgnoredRecordsWithFieldPattern
Definition: UninitializedObject.h:77
shouldIgnoreRecord
static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern)
Checks whether RD contains a field with a name or type name that matches Pattern.
Definition: UninitializedObjectChecker.cpp:502
DynamicType.h
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:687
clang::ento::FieldChainInfo::printNoteMsg
void printNoteMsg(llvm::raw_ostream &Out) const
Definition: UninitializedObjectChecker.cpp:424
clang::ento::UninitObjCheckerOptions::ShouldConvertNotesToWarnings
bool ShouldConvertNotesToWarnings
Definition: UninitializedObject.h:75
clang::ento::UninitFieldMap
std::map< const FieldRegion *, llvm::SmallString< 50 > > UninitFieldMap
Definition: UninitializedObject.h:194
clang::ento::FieldChainInfo
Represents a field chain.
Definition: UninitializedObject.h:160
clang::ast_matchers::hasDeclaration
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
Definition: ASTMatchers.h:3563
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:430
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:247
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3859
clang::FunctionDecl::isDefined
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Definition: Decl.cpp:3002
clang::ast_matchers::conditionalOperator
const internal::VariadicDynCastAllOfMatcher< Stmt, ConditionalOperator > conditionalOperator
Matches conditional operator expressions.
Definition: ASTMatchersInternal.cpp:953
clang::ento::FindUninitializedFields
Searches for and stores uninitialized fields in a non-union object.
Definition: UninitializedObject.h:197
llvm::IntrusiveRefCntPtr
Definition: LLVM.h:47
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::ReturnStmt
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2760
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1948