clang  3.7.0
CallAndMessageChecker.cpp
Go to the documentation of this file.
1 //===--- CallAndMessageChecker.cpp ------------------------------*- C++ -*--==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This defines CallAndMessageChecker, a builtin checker that checks for various
11 // errors of call and objc message expressions.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ClangSACheckers.h"
16 #include "clang/AST/ParentMap.h"
17 #include "clang/Basic/TargetInfo.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 using namespace clang;
27 using namespace ento;
28 
29 namespace {
30 
31 struct ChecksFilter {
32  DefaultBool Check_CallAndMessageUnInitRefArg;
33  DefaultBool Check_CallAndMessageChecker;
34 
35  CheckName CheckName_CallAndMessageUnInitRefArg;
36  CheckName CheckName_CallAndMessageChecker;
37 };
38 
39 class CallAndMessageChecker
40  : public Checker< check::PreStmt<CallExpr>,
41  check::PreStmt<CXXDeleteExpr>,
42  check::PreObjCMessage,
43  check::PreCall > {
44  mutable std::unique_ptr<BugType> BT_call_null;
45  mutable std::unique_ptr<BugType> BT_call_undef;
46  mutable std::unique_ptr<BugType> BT_cxx_call_null;
47  mutable std::unique_ptr<BugType> BT_cxx_call_undef;
48  mutable std::unique_ptr<BugType> BT_call_arg;
49  mutable std::unique_ptr<BugType> BT_cxx_delete_undef;
50  mutable std::unique_ptr<BugType> BT_msg_undef;
51  mutable std::unique_ptr<BugType> BT_objc_prop_undef;
52  mutable std::unique_ptr<BugType> BT_objc_subscript_undef;
53  mutable std::unique_ptr<BugType> BT_msg_arg;
54  mutable std::unique_ptr<BugType> BT_msg_ret;
55  mutable std::unique_ptr<BugType> BT_call_few_args;
56 
57 public:
58  ChecksFilter Filter;
59 
60  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
61  void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
62  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
63  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
64 
65 private:
66  bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
67  const Expr *ArgEx, bool IsFirstArgument,
68  bool CheckUninitFields, const CallEvent &Call,
69  std::unique_ptr<BugType> &BT,
70  const ParmVarDecl *ParamDecl) const;
71 
72  static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
73  void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
74  ExplodedNode *N) const;
75 
76  void HandleNilReceiver(CheckerContext &C,
77  ProgramStateRef state,
78  const ObjCMethodCall &msg) const;
79 
80  void LazyInit_BT(const char *desc, std::unique_ptr<BugType> &BT) const {
81  if (!BT)
82  BT.reset(new BuiltinBug(this, desc));
83  }
84  bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
85  const SourceRange &ArgRange,
86  const Expr *ArgEx, std::unique_ptr<BugType> &BT,
87  const ParmVarDecl *ParamDecl, const char *BD) const;
88 };
89 } // end anonymous namespace
90 
91 void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
92  const Expr *BadE) {
93  ExplodedNode *N = C.generateSink();
94  if (!N)
95  return;
96 
97  auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
98  if (BadE) {
99  R->addRange(BadE->getSourceRange());
100  if (BadE->isGLValue())
101  BadE = bugreporter::getDerefExpr(BadE);
103  }
104  C.emitReport(std::move(R));
105 }
106 
107 static StringRef describeUninitializedArgumentInCall(const CallEvent &Call,
108  bool IsFirstArgument) {
109  switch (Call.getKind()) {
110  case CE_ObjCMessage: {
111  const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
112  switch (Msg.getMessageKind()) {
113  case OCM_Message:
114  return "Argument in message expression is an uninitialized value";
115  case OCM_PropertyAccess:
116  assert(Msg.isSetter() && "Getters have no args");
117  return "Argument for property setter is an uninitialized value";
118  case OCM_Subscript:
119  if (Msg.isSetter() && IsFirstArgument)
120  return "Argument for subscript setter is an uninitialized value";
121  return "Subscript index is an uninitialized value";
122  }
123  llvm_unreachable("Unknown message kind.");
124  }
125  case CE_Block:
126  return "Block call argument is an uninitialized value";
127  default:
128  return "Function call argument is an uninitialized value";
129  }
130 }
131 
132 bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C,
133  const SVal &V,
134  const SourceRange &ArgRange,
135  const Expr *ArgEx,
136  std::unique_ptr<BugType> &BT,
137  const ParmVarDecl *ParamDecl,
138  const char *BD) const {
139  if (!Filter.Check_CallAndMessageUnInitRefArg)
140  return false;
141 
142  // No parameter declaration available, i.e. variadic function argument.
143  if(!ParamDecl)
144  return false;
145 
146  // If parameter is declared as pointer to const in function declaration,
147  // then check if corresponding argument in function call is
148  // pointing to undefined symbol value (uninitialized memory).
149  StringRef Message;
150 
151  if (ParamDecl->getType()->isPointerType()) {
152  Message = "Function call argument is a pointer to uninitialized value";
153  } else if (ParamDecl->getType()->isReferenceType()) {
154  Message = "Function call argument is an uninitialized value";
155  } else
156  return false;
157 
158  if(!ParamDecl->getType()->getPointeeType().isConstQualified())
159  return false;
160 
161  if (const MemRegion *SValMemRegion = V.getAsRegion()) {
162  const ProgramStateRef State = C.getState();
163  const SVal PSV = State->getSVal(SValMemRegion);
164  if (PSV.isUndef()) {
165  if (ExplodedNode *N = C.generateSink()) {
166  LazyInit_BT(BD, BT);
167  auto R = llvm::make_unique<BugReport>(*BT, Message, N);
168  R->addRange(ArgRange);
169  if (ArgEx) {
171  }
172  C.emitReport(std::move(R));
173  }
174  return true;
175  }
176  }
177  return false;
178 }
179 
180 bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
181  SVal V,
182  SourceRange ArgRange,
183  const Expr *ArgEx,
184  bool IsFirstArgument,
185  bool CheckUninitFields,
186  const CallEvent &Call,
187  std::unique_ptr<BugType> &BT,
188  const ParmVarDecl *ParamDecl
189  ) const {
190  const char *BD = "Uninitialized argument value";
191 
192  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD))
193  return true;
194 
195  if (V.isUndef()) {
196  if (ExplodedNode *N = C.generateSink()) {
197  LazyInit_BT(BD, BT);
198 
199  // Generate a report for this bug.
200  StringRef Desc =
201  describeUninitializedArgumentInCall(Call, IsFirstArgument);
202  auto R = llvm::make_unique<BugReport>(*BT, Desc, N);
203  R->addRange(ArgRange);
204  if (ArgEx)
206  C.emitReport(std::move(R));
207  }
208  return true;
209  }
210 
211  if (!CheckUninitFields)
212  return false;
213 
216 
217  class FindUninitializedField {
218  public:
220  private:
221  StoreManager &StoreMgr;
222  MemRegionManager &MrMgr;
223  Store store;
224  public:
225  FindUninitializedField(StoreManager &storeMgr,
226  MemRegionManager &mrMgr, Store s)
227  : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
228 
229  bool Find(const TypedValueRegion *R) {
230  QualType T = R->getValueType();
231  if (const RecordType *RT = T->getAsStructureType()) {
232  const RecordDecl *RD = RT->getDecl()->getDefinition();
233  assert(RD && "Referred record has no definition");
234  for (const auto *I : RD->fields()) {
235  const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
236  FieldChain.push_back(I);
237  T = I->getType();
238  if (T->getAsStructureType()) {
239  if (Find(FR))
240  return true;
241  }
242  else {
243  const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
244  if (V.isUndef())
245  return true;
246  }
247  FieldChain.pop_back();
248  }
249  }
250 
251  return false;
252  }
253  };
254 
255  const LazyCompoundValData *D = LV->getCVData();
256  FindUninitializedField F(C.getState()->getStateManager().getStoreManager(),
258  D->getStore());
259 
260  if (F.Find(D->getRegion())) {
261  if (ExplodedNode *N = C.generateSink()) {
262  LazyInit_BT(BD, BT);
263  SmallString<512> Str;
264  llvm::raw_svector_ostream os(Str);
265  os << "Passed-by-value struct argument contains uninitialized data";
266 
267  if (F.FieldChain.size() == 1)
268  os << " (e.g., field: '" << *F.FieldChain[0] << "')";
269  else {
270  os << " (e.g., via the field chain: '";
271  bool first = true;
273  DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){
274  if (first)
275  first = false;
276  else
277  os << '.';
278  os << **DI;
279  }
280  os << "')";
281  }
282 
283  // Generate a report for this bug.
284  auto R = llvm::make_unique<BugReport>(*BT, os.str(), N);
285  R->addRange(ArgRange);
286 
287  // FIXME: enhance track back for uninitialized value for arbitrary
288  // memregions
289  C.emitReport(std::move(R));
290  }
291  return true;
292  }
293  }
294 
295  return false;
296 }
297 
298 void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
299  CheckerContext &C) const{
300 
301  const Expr *Callee = CE->getCallee()->IgnoreParens();
302  ProgramStateRef State = C.getState();
303  const LocationContext *LCtx = C.getLocationContext();
304  SVal L = State->getSVal(Callee, LCtx);
305 
306  if (L.isUndef()) {
307  if (!BT_call_undef)
308  BT_call_undef.reset(new BuiltinBug(
309  this, "Called function pointer is an uninitalized pointer value"));
310  emitBadCall(BT_call_undef.get(), C, Callee);
311  return;
312  }
313 
314  ProgramStateRef StNonNull, StNull;
315  std::tie(StNonNull, StNull) = State->assume(L.castAs<DefinedOrUnknownSVal>());
316 
317  if (StNull && !StNonNull) {
318  if (!BT_call_null)
319  BT_call_null.reset(new BuiltinBug(
320  this, "Called function pointer is null (null dereference)"));
321  emitBadCall(BT_call_null.get(), C, Callee);
322  return;
323  }
324 
325  C.addTransition(StNonNull);
326 }
327 
328 void CallAndMessageChecker::checkPreStmt(const CXXDeleteExpr *DE,
329  CheckerContext &C) const {
330 
331  SVal Arg = C.getSVal(DE->getArgument());
332  if (Arg.isUndef()) {
333  StringRef Desc;
334  ExplodedNode *N = C.generateSink();
335  if (!N)
336  return;
337  if (!BT_cxx_delete_undef)
338  BT_cxx_delete_undef.reset(
339  new BuiltinBug(this, "Uninitialized argument value"));
340  if (DE->isArrayFormAsWritten())
341  Desc = "Argument to 'delete[]' is uninitialized";
342  else
343  Desc = "Argument to 'delete' is uninitialized";
344  BugType *BT = BT_cxx_delete_undef.get();
345  auto R = llvm::make_unique<BugReport>(*BT, Desc, N);
347  C.emitReport(std::move(R));
348  return;
349  }
350 }
351 
352 
353 void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
354  CheckerContext &C) const {
355  ProgramStateRef State = C.getState();
356 
357  // If this is a call to a C++ method, check if the callee is null or
358  // undefined.
359  if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
360  SVal V = CC->getCXXThisVal();
361  if (V.isUndef()) {
362  if (!BT_cxx_call_undef)
363  BT_cxx_call_undef.reset(
364  new BuiltinBug(this, "Called C++ object pointer is uninitialized"));
365  emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
366  return;
367  }
368 
369  ProgramStateRef StNonNull, StNull;
370  std::tie(StNonNull, StNull) =
371  State->assume(V.castAs<DefinedOrUnknownSVal>());
372 
373  if (StNull && !StNonNull) {
374  if (!BT_cxx_call_null)
375  BT_cxx_call_null.reset(
376  new BuiltinBug(this, "Called C++ object pointer is null"));
377  emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
378  return;
379  }
380 
381  State = StNonNull;
382  }
383 
384  const Decl *D = Call.getDecl();
385  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
386  if (FD) {
387  // If we have a declaration, we can make sure we pass enough parameters to
388  // the function.
389  unsigned Params = FD->getNumParams();
390  if (Call.getNumArgs() < Params) {
391  ExplodedNode *N = C.generateSink();
392  if (!N)
393  return;
394 
395  LazyInit_BT("Function call with too few arguments", BT_call_few_args);
396 
397  SmallString<512> Str;
398  llvm::raw_svector_ostream os(Str);
399  os << "Function taking " << Params << " argument"
400  << (Params == 1 ? "" : "s") << " is called with less ("
401  << Call.getNumArgs() << ")";
402 
403  C.emitReport(
404  llvm::make_unique<BugReport>(*BT_call_few_args, os.str(), N));
405  }
406  }
407 
408  // Don't check for uninitialized field values in arguments if the
409  // caller has a body that is available and we have the chance to inline it.
410  // This is a hack, but is a reasonable compromise betweens sometimes warning
411  // and sometimes not depending on if we decide to inline a function.
412  const bool checkUninitFields =
413  !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));
414 
415  std::unique_ptr<BugType> *BT;
416  if (isa<ObjCMethodCall>(Call))
417  BT = &BT_msg_arg;
418  else
419  BT = &BT_call_arg;
420 
421  for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) {
422  const ParmVarDecl *ParamDecl = nullptr;
423  if(FD && i < FD->getNumParams())
424  ParamDecl = FD->getParamDecl(i);
425  if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
426  Call.getArgExpr(i), /*IsFirstArgument=*/i == 0,
427  checkUninitFields, Call, *BT, ParamDecl))
428  return;
429  }
430 
431  // If we make it here, record our assumptions about the callee.
432  C.addTransition(State);
433 }
434 
435 void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
436  CheckerContext &C) const {
437  SVal recVal = msg.getReceiverSVal();
438  if (recVal.isUndef()) {
439  if (ExplodedNode *N = C.generateSink()) {
440  BugType *BT = nullptr;
441  switch (msg.getMessageKind()) {
442  case OCM_Message:
443  if (!BT_msg_undef)
444  BT_msg_undef.reset(new BuiltinBug(this,
445  "Receiver in message expression "
446  "is an uninitialized value"));
447  BT = BT_msg_undef.get();
448  break;
449  case OCM_PropertyAccess:
450  if (!BT_objc_prop_undef)
451  BT_objc_prop_undef.reset(new BuiltinBug(
452  this, "Property access on an uninitialized object pointer"));
453  BT = BT_objc_prop_undef.get();
454  break;
455  case OCM_Subscript:
456  if (!BT_objc_subscript_undef)
457  BT_objc_subscript_undef.reset(new BuiltinBug(
458  this, "Subscript access on an uninitialized object pointer"));
459  BT = BT_objc_subscript_undef.get();
460  break;
461  }
462  assert(BT && "Unknown message kind.");
463 
464  auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
465  const ObjCMessageExpr *ME = msg.getOriginExpr();
466  R->addRange(ME->getReceiverRange());
467 
468  // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
469  if (const Expr *ReceiverE = ME->getInstanceReceiver())
470  bugreporter::trackNullOrUndefValue(N, ReceiverE, *R);
471  C.emitReport(std::move(R));
472  }
473  return;
474  } else {
475  // Bifurcate the state into nil and non-nil ones.
476  DefinedOrUnknownSVal receiverVal = recVal.castAs<DefinedOrUnknownSVal>();
477 
478  ProgramStateRef state = C.getState();
479  ProgramStateRef notNilState, nilState;
480  std::tie(notNilState, nilState) = state->assume(receiverVal);
481 
482  // Handle receiver must be nil.
483  if (nilState && !notNilState) {
484  HandleNilReceiver(C, state, msg);
485  return;
486  }
487  }
488 }
489 
490 void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
491  const ObjCMethodCall &msg,
492  ExplodedNode *N) const {
493 
494  if (!BT_msg_ret)
495  BT_msg_ret.reset(
496  new BuiltinBug(this, "Receiver in message expression is 'nil'"));
497 
498  const ObjCMessageExpr *ME = msg.getOriginExpr();
499 
500  QualType ResTy = msg.getResultType();
501 
502  SmallString<200> buf;
503  llvm::raw_svector_ostream os(buf);
504  os << "The receiver of message '";
505  ME->getSelector().print(os);
506  os << "' is nil";
507  if (ResTy->isReferenceType()) {
508  os << ", which results in forming a null reference";
509  } else {
510  os << " and returns a value of type '";
511  msg.getResultType().print(os, C.getLangOpts());
512  os << "' that will be garbage";
513  }
514 
515  auto report = llvm::make_unique<BugReport>(*BT_msg_ret, os.str(), N);
516  report->addRange(ME->getReceiverRange());
517  // FIXME: This won't track "self" in messages to super.
518  if (const Expr *receiver = ME->getInstanceReceiver()) {
519  bugreporter::trackNullOrUndefValue(N, receiver, *report);
520  }
521  C.emitReport(std::move(report));
522 }
523 
524 static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
525  return (triple.getVendor() == llvm::Triple::Apple &&
526  (triple.isiOS() || !triple.isMacOSXVersionLT(10,5)));
527 }
528 
529 void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
530  ProgramStateRef state,
531  const ObjCMethodCall &Msg) const {
532  ASTContext &Ctx = C.getASTContext();
533  static CheckerProgramPointTag Tag(this, "NilReceiver");
534 
535  // Check the return type of the message expression. A message to nil will
536  // return different values depending on the return type and the architecture.
537  QualType RetTy = Msg.getResultType();
538  CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
539  const LocationContext *LCtx = C.getLocationContext();
540 
541  if (CanRetTy->isStructureOrClassType()) {
542  // Structure returns are safe since the compiler zeroes them out.
543  SVal V = C.getSValBuilder().makeZeroVal(RetTy);
544  C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
545  return;
546  }
547 
548  // Other cases: check if sizeof(return type) > sizeof(void*)
549  if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
550  .isConsumedExpr(Msg.getOriginExpr())) {
551  // Compute: sizeof(void *) and sizeof(return type)
552  const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
553  const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
554 
555  if (CanRetTy.getTypePtr()->isReferenceType()||
556  (voidPtrSize < returnTypeSize &&
558  (Ctx.FloatTy == CanRetTy ||
559  Ctx.DoubleTy == CanRetTy ||
560  Ctx.LongDoubleTy == CanRetTy ||
561  Ctx.LongLongTy == CanRetTy ||
562  Ctx.UnsignedLongLongTy == CanRetTy)))) {
563  if (ExplodedNode *N = C.generateSink(state, nullptr, &Tag))
564  emitNilReceiverBug(C, Msg, N);
565  return;
566  }
567 
568  // Handle the safe cases where the return value is 0 if the
569  // receiver is nil.
570  //
571  // FIXME: For now take the conservative approach that we only
572  // return null values if we *know* that the receiver is nil.
573  // This is because we can have surprises like:
574  //
575  // ... = [[NSScreens screens] objectAtIndex:0];
576  //
577  // What can happen is that [... screens] could return nil, but
578  // it most likely isn't nil. We should assume the semantics
579  // of this case unless we have *a lot* more knowledge.
580  //
581  SVal V = C.getSValBuilder().makeZeroVal(RetTy);
582  C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
583  return;
584  }
585 
586  C.addTransition(state);
587 }
588 
589 #define REGISTER_CHECKER(name) \
590  void ento::register##name(CheckerManager &mgr) { \
591  CallAndMessageChecker *Checker = \
592  mgr.registerChecker<CallAndMessageChecker>(); \
593  Checker->Filter.Check_##name = true; \
594  Checker->Filter.CheckName_##name = mgr.getCurrentCheckName(); \
595  }
596 
597 REGISTER_CHECKER(CallAndMessageUnInitRefArg)
598 REGISTER_CHECKER(CallAndMessageChecker)
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:195
CanQualType LongLongTy
Definition: ASTContext.h:825
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:498
const Expr * getDerefExpr(const Stmt *S)
CanQualType VoidPtrTy
Definition: ASTContext.h:831
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:77
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:523
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph). Uses the default CheckerContex...
virtual QualType getValueType() const =0
const void * Store
Definition: StoreRef.h:26
AnalysisManager & getAnalysisManager()
static StringRef describeUninitializedArgumentInCall(const CallEvent &Call, bool IsFirstArgument)
const Expr * getCallee() const
Definition: Expr.h:2188
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:1701
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1334
MemRegionManager & getRegionManager()
Definition: SValBuilder.h:140
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
LineState State
bool isReferenceType() const
Definition: Type.h:5241
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:791
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:518
virtual Kind getKind() const =0
Returns the kind of call this is.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
Definition: CallEvent.cpp:627
field_range fields() const
Definition: Decl.h:3349
Selector getSelector() const
Definition: Expr.cpp:3718
CanQualType LongDoubleTy
Definition: ASTContext.h:828
bool isSetter() const
Definition: CallEvent.h:861
const TypedValueRegion * getRegion() const
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
QualType getType() const
Definition: Decl.h:538
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Definition: CallEvent.cpp:202
#define REGISTER_CHECKER(name)
StringRef getName() const
Definition: BugType.h:48
ExplodedNode * generateSink(ProgramStateRef State=nullptr, ExplodedNode *Pred=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a sink node. Generating a sink stops exploration of the given path.
Represents a non-static C++ member function call, no matter how it is written.
Definition: CallEvent.h:522
QualType getPointeeType() const
Definition: Type.cpp:414
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
Definition: SValBuilder.cpp:32
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument. May be null if this expression does not appe...
Definition: CallEvent.h:240
const ProgramStateRef & getState() const
SourceRange getReceiverRange() const
Source range of the receiver.
Definition: Expr.cpp:3702
ParentMap & getParentMap() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:86
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:1968
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:858
bool isGLValue() const
Definition: Expr.h:253
RecordDecl * getDefinition() const
Definition: Decl.h:3339
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Expr * getArgument()
Definition: ExprCXX.h:1866
bool isConsumedExpr(Expr *E) const
Definition: ParentMap.cpp:157
unsigned getNumParams() const
Definition: Decl.cpp:2651
CanQualType FloatTy
Definition: ASTContext.h:828
virtual Stmt * getBody() const
Definition: DeclBase.h:840
CanQualType VoidTy
Definition: ASTContext.h:817
bool isUndef() const
Definition: SVals.h:121
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called. May be null.
Definition: CallEvent.h:177
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1152
Represents a delete expression for memory deallocation and destructor calls, e.g. "delete[] pArray"...
Definition: ExprCXX.h:1819
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:827
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const MemRegion * getAsRegion() const
Definition: SVals.cpp:135
for(auto typeArg:T->getTypeArgsAsWritten())
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:1855
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:113
ObjCMessageKind getMessageKind() const
Definition: CallEvent.cpp:675
const RecordType * getAsStructureType() const
Definition: Type.cpp:430
static bool supportsNilWithFloatRet(const llvm::Triple &triple)
const LangOptions & getLangOpts() const
bool isArrayFormAsWritten() const
Definition: ExprCXX.h:1854
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:70
SValBuilder & getSValBuilder()
Defines the clang::TargetInfo interface.
A trivial tuple used to represent a source range.
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:5075
CanQualType DoubleTy
Definition: ASTContext.h:828
virtual const ObjCMessageExpr * getOriginExpr() const
Definition: CallEvent.h:813
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:75
Expr * IgnoreParens() LLVM_READONLY
Definition: Expr.cpp:2408
const LocationContext * getLocationContext() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
bool isPointerType() const
Definition: Type.h:5232