clang  10.0.0svn
CallAndMessageChecker.cpp
Go to the documentation of this file.
1 //===--- CallAndMessageChecker.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 defines CallAndMessageChecker, a builtin checker that checks for various
10 // errors of call and objc message expressions.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/ParentMap.h"
16 #include "clang/Basic/TargetInfo.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 using namespace clang;
27 using namespace ento;
28 
29 namespace {
30 
31 class CallAndMessageChecker
32  : public Checker< check::PreStmt<CallExpr>,
33  check::PreStmt<CXXDeleteExpr>,
34  check::PreObjCMessage,
35  check::ObjCMessageNil,
36  check::PreCall > {
37  mutable std::unique_ptr<BugType> BT_call_null;
38  mutable std::unique_ptr<BugType> BT_call_undef;
39  mutable std::unique_ptr<BugType> BT_cxx_call_null;
40  mutable std::unique_ptr<BugType> BT_cxx_call_undef;
41  mutable std::unique_ptr<BugType> BT_call_arg;
42  mutable std::unique_ptr<BugType> BT_cxx_delete_undef;
43  mutable std::unique_ptr<BugType> BT_msg_undef;
44  mutable std::unique_ptr<BugType> BT_objc_prop_undef;
45  mutable std::unique_ptr<BugType> BT_objc_subscript_undef;
46  mutable std::unique_ptr<BugType> BT_msg_arg;
47  mutable std::unique_ptr<BugType> BT_msg_ret;
48  mutable std::unique_ptr<BugType> BT_call_few_args;
49 
50 public:
51  DefaultBool Check_CallAndMessageUnInitRefArg;
52  CheckerNameRef CheckName_CallAndMessageUnInitRefArg;
53 
54  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
55  void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
56  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
57 
58  /// Fill in the return value that results from messaging nil based on the
59  /// return type and architecture and diagnose if the return value will be
60  /// garbage.
61  void checkObjCMessageNil(const ObjCMethodCall &msg, CheckerContext &C) const;
62 
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, int ArgumentNumber,
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,
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  SourceRange ArgRange, const Expr *ArgEx,
86  std::unique_ptr<BugType> &BT,
87  const ParmVarDecl *ParamDecl, const char *BD,
88  int ArgumentNumber) const;
89 };
90 } // end anonymous namespace
91 
92 void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
93  const Expr *BadE) {
94  ExplodedNode *N = C.generateErrorNode();
95  if (!N)
96  return;
97 
98  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
99  if (BadE) {
100  R->addRange(BadE->getSourceRange());
101  if (BadE->isGLValue())
102  BadE = bugreporter::getDerefExpr(BadE);
103  bugreporter::trackExpressionValue(N, BadE, *R);
104  }
105  C.emitReport(std::move(R));
106 }
107 
109  int ArgumentNumber,
110  llvm::raw_svector_ostream &Os) {
111  switch (Call.getKind()) {
112  case CE_ObjCMessage: {
113  const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
114  switch (Msg.getMessageKind()) {
115  case OCM_Message:
116  Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
117  << " argument in message expression is an uninitialized value";
118  return;
119  case OCM_PropertyAccess:
120  assert(Msg.isSetter() && "Getters have no args");
121  Os << "Argument for property setter is an uninitialized value";
122  return;
123  case OCM_Subscript:
124  if (Msg.isSetter() && (ArgumentNumber == 0))
125  Os << "Argument for subscript setter is an uninitialized value";
126  else
127  Os << "Subscript index is an uninitialized value";
128  return;
129  }
130  llvm_unreachable("Unknown message kind.");
131  }
132  case CE_Block:
133  Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
134  << " block call argument is an uninitialized value";
135  return;
136  default:
137  Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
138  << " function call argument is an uninitialized value";
139  return;
140  }
141 }
142 
143 bool CallAndMessageChecker::uninitRefOrPointer(
144  CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
145  std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
146  int ArgumentNumber) const {
147  if (!Check_CallAndMessageUnInitRefArg)
148  return false;
149 
150  // No parameter declaration available, i.e. variadic function argument.
151  if(!ParamDecl)
152  return false;
153 
154  // If parameter is declared as pointer to const in function declaration,
155  // then check if corresponding argument in function call is
156  // pointing to undefined symbol value (uninitialized memory).
157  SmallString<200> Buf;
158  llvm::raw_svector_ostream Os(Buf);
159 
160  if (ParamDecl->getType()->isPointerType()) {
161  Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
162  << " function call argument is a pointer to uninitialized value";
163  } else if (ParamDecl->getType()->isReferenceType()) {
164  Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
165  << " function call argument is an uninitialized value";
166  } else
167  return false;
168 
169  if(!ParamDecl->getType()->getPointeeType().isConstQualified())
170  return false;
171 
172  if (const MemRegion *SValMemRegion = V.getAsRegion()) {
173  const ProgramStateRef State = C.getState();
174  const SVal PSV = State->getSVal(SValMemRegion, C.getASTContext().CharTy);
175  if (PSV.isUndef()) {
176  if (ExplodedNode *N = C.generateErrorNode()) {
177  LazyInit_BT(BD, BT);
178  auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);
179  R->addRange(ArgRange);
180  if (ArgEx)
181  bugreporter::trackExpressionValue(N, ArgEx, *R);
182 
183  C.emitReport(std::move(R));
184  }
185  return true;
186  }
187  }
188  return false;
189 }
190 
191 namespace {
192 class FindUninitializedField {
193 public:
195 
196 private:
197  StoreManager &StoreMgr;
198  MemRegionManager &MrMgr;
199  Store store;
200 
201 public:
202  FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr,
203  Store s)
204  : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
205 
206  bool Find(const TypedValueRegion *R) {
207  QualType T = R->getValueType();
208  if (const RecordType *RT = T->getAsStructureType()) {
209  const RecordDecl *RD = RT->getDecl()->getDefinition();
210  assert(RD && "Referred record has no definition");
211  for (const auto *I : RD->fields()) {
212  const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
213  FieldChain.push_back(I);
214  T = I->getType();
215  if (T->getAsStructureType()) {
216  if (Find(FR))
217  return true;
218  } else {
219  const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
220  if (V.isUndef())
221  return true;
222  }
223  FieldChain.pop_back();
224  }
225  }
226 
227  return false;
228  }
229 };
230 } // namespace
231 
232 bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
233  SVal V,
234  SourceRange ArgRange,
235  const Expr *ArgEx,
236  int ArgumentNumber,
237  bool CheckUninitFields,
238  const CallEvent &Call,
239  std::unique_ptr<BugType> &BT,
240  const ParmVarDecl *ParamDecl
241  ) const {
242  const char *BD = "Uninitialized argument value";
243 
244  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD,
245  ArgumentNumber))
246  return true;
247 
248  if (V.isUndef()) {
249  if (ExplodedNode *N = C.generateErrorNode()) {
250  LazyInit_BT(BD, BT);
251  // Generate a report for this bug.
252  SmallString<200> Buf;
253  llvm::raw_svector_ostream Os(Buf);
254  describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
255  auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);
256 
257  R->addRange(ArgRange);
258  if (ArgEx)
259  bugreporter::trackExpressionValue(N, ArgEx, *R);
260  C.emitReport(std::move(R));
261  }
262  return true;
263  }
264 
265  if (!CheckUninitFields)
266  return false;
267 
268  if (auto LV = V.getAs<nonloc::LazyCompoundVal>()) {
269  const LazyCompoundValData *D = LV->getCVData();
270  FindUninitializedField F(C.getState()->getStateManager().getStoreManager(),
271  C.getSValBuilder().getRegionManager(),
272  D->getStore());
273 
274  if (F.Find(D->getRegion())) {
275  if (ExplodedNode *N = C.generateErrorNode()) {
276  LazyInit_BT(BD, BT);
277  SmallString<512> Str;
278  llvm::raw_svector_ostream os(Str);
279  os << "Passed-by-value struct argument contains uninitialized data";
280 
281  if (F.FieldChain.size() == 1)
282  os << " (e.g., field: '" << *F.FieldChain[0] << "')";
283  else {
284  os << " (e.g., via the field chain: '";
285  bool first = true;
287  DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){
288  if (first)
289  first = false;
290  else
291  os << '.';
292  os << **DI;
293  }
294  os << "')";
295  }
296 
297  // Generate a report for this bug.
298  auto R = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
299  R->addRange(ArgRange);
300 
301  if (ArgEx)
302  bugreporter::trackExpressionValue(N, ArgEx, *R);
303  // FIXME: enhance track back for uninitialized value for arbitrary
304  // memregions
305  C.emitReport(std::move(R));
306  }
307  return true;
308  }
309  }
310 
311  return false;
312 }
313 
314 void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
315  CheckerContext &C) const{
316 
317  const Expr *Callee = CE->getCallee()->IgnoreParens();
318  ProgramStateRef State = C.getState();
319  const LocationContext *LCtx = C.getLocationContext();
320  SVal L = State->getSVal(Callee, LCtx);
321 
322  if (L.isUndef()) {
323  if (!BT_call_undef)
324  BT_call_undef.reset(new BuiltinBug(
325  this, "Called function pointer is an uninitialized pointer value"));
326  emitBadCall(BT_call_undef.get(), C, Callee);
327  return;
328  }
329 
330  ProgramStateRef StNonNull, StNull;
331  std::tie(StNonNull, StNull) = State->assume(L.castAs<DefinedOrUnknownSVal>());
332 
333  if (StNull && !StNonNull) {
334  if (!BT_call_null)
335  BT_call_null.reset(new BuiltinBug(
336  this, "Called function pointer is null (null dereference)"));
337  emitBadCall(BT_call_null.get(), C, Callee);
338  return;
339  }
340 
341  C.addTransition(StNonNull);
342 }
343 
344 void CallAndMessageChecker::checkPreStmt(const CXXDeleteExpr *DE,
345  CheckerContext &C) const {
346 
347  SVal Arg = C.getSVal(DE->getArgument());
348  if (Arg.isUndef()) {
349  StringRef Desc;
350  ExplodedNode *N = C.generateErrorNode();
351  if (!N)
352  return;
353  if (!BT_cxx_delete_undef)
354  BT_cxx_delete_undef.reset(
355  new BuiltinBug(this, "Uninitialized argument value"));
356  if (DE->isArrayFormAsWritten())
357  Desc = "Argument to 'delete[]' is uninitialized";
358  else
359  Desc = "Argument to 'delete' is uninitialized";
360  BugType *BT = BT_cxx_delete_undef.get();
361  auto R = std::make_unique<PathSensitiveBugReport>(*BT, Desc, N);
362  bugreporter::trackExpressionValue(N, DE, *R);
363  C.emitReport(std::move(R));
364  return;
365  }
366 }
367 
368 void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
369  CheckerContext &C) const {
370  ProgramStateRef State = C.getState();
371 
372  // If this is a call to a C++ method, check if the callee is null or
373  // undefined.
374  if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
375  SVal V = CC->getCXXThisVal();
376  if (V.isUndef()) {
377  if (!BT_cxx_call_undef)
378  BT_cxx_call_undef.reset(
379  new BuiltinBug(this, "Called C++ object pointer is uninitialized"));
380  emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
381  return;
382  }
383 
384  ProgramStateRef StNonNull, StNull;
385  std::tie(StNonNull, StNull) =
386  State->assume(V.castAs<DefinedOrUnknownSVal>());
387 
388  if (StNull && !StNonNull) {
389  if (!BT_cxx_call_null)
390  BT_cxx_call_null.reset(
391  new BuiltinBug(this, "Called C++ object pointer is null"));
392  emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
393  return;
394  }
395 
396  State = StNonNull;
397  }
398 
399  const Decl *D = Call.getDecl();
400  if (D && (isa<FunctionDecl>(D) || isa<BlockDecl>(D))) {
401  // If we have a function or block declaration, we can make sure we pass
402  // enough parameters.
403  unsigned Params = Call.parameters().size();
404  if (Call.getNumArgs() < Params) {
405  ExplodedNode *N = C.generateErrorNode();
406  if (!N)
407  return;
408 
409  LazyInit_BT("Function call with too few arguments", BT_call_few_args);
410 
411  SmallString<512> Str;
412  llvm::raw_svector_ostream os(Str);
413  if (isa<FunctionDecl>(D)) {
414  os << "Function ";
415  } else {
416  assert(isa<BlockDecl>(D));
417  os << "Block ";
418  }
419  os << "taking " << Params << " argument"
420  << (Params == 1 ? "" : "s") << " is called with fewer ("
421  << Call.getNumArgs() << ")";
422 
423  C.emitReport(std::make_unique<PathSensitiveBugReport>(*BT_call_few_args,
424  os.str(), N));
425  }
426  }
427 
428  // Don't check for uninitialized field values in arguments if the
429  // caller has a body that is available and we have the chance to inline it.
430  // This is a hack, but is a reasonable compromise betweens sometimes warning
431  // and sometimes not depending on if we decide to inline a function.
432  const bool checkUninitFields =
433  !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));
434 
435  std::unique_ptr<BugType> *BT;
436  if (isa<ObjCMethodCall>(Call))
437  BT = &BT_msg_arg;
438  else
439  BT = &BT_call_arg;
440 
441  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
442  for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) {
443  const ParmVarDecl *ParamDecl = nullptr;
444  if(FD && i < FD->getNumParams())
445  ParamDecl = FD->getParamDecl(i);
446  if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
447  Call.getArgExpr(i), i,
448  checkUninitFields, Call, *BT, ParamDecl))
449  return;
450  }
451 
452  // If we make it here, record our assumptions about the callee.
453  C.addTransition(State);
454 }
455 
456 void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
457  CheckerContext &C) const {
458  SVal recVal = msg.getReceiverSVal();
459  if (recVal.isUndef()) {
460  if (ExplodedNode *N = C.generateErrorNode()) {
461  BugType *BT = nullptr;
462  switch (msg.getMessageKind()) {
463  case OCM_Message:
464  if (!BT_msg_undef)
465  BT_msg_undef.reset(new BuiltinBug(this,
466  "Receiver in message expression "
467  "is an uninitialized value"));
468  BT = BT_msg_undef.get();
469  break;
470  case OCM_PropertyAccess:
471  if (!BT_objc_prop_undef)
472  BT_objc_prop_undef.reset(new BuiltinBug(
473  this, "Property access on an uninitialized object pointer"));
474  BT = BT_objc_prop_undef.get();
475  break;
476  case OCM_Subscript:
477  if (!BT_objc_subscript_undef)
478  BT_objc_subscript_undef.reset(new BuiltinBug(
479  this, "Subscript access on an uninitialized object pointer"));
480  BT = BT_objc_subscript_undef.get();
481  break;
482  }
483  assert(BT && "Unknown message kind.");
484 
485  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
486  const ObjCMessageExpr *ME = msg.getOriginExpr();
487  R->addRange(ME->getReceiverRange());
488 
489  // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
490  if (const Expr *ReceiverE = ME->getInstanceReceiver())
491  bugreporter::trackExpressionValue(N, ReceiverE, *R);
492  C.emitReport(std::move(R));
493  }
494  return;
495  }
496 }
497 
498 void CallAndMessageChecker::checkObjCMessageNil(const ObjCMethodCall &msg,
499  CheckerContext &C) const {
500  HandleNilReceiver(C, C.getState(), msg);
501 }
502 
503 void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
504  const ObjCMethodCall &msg,
505  ExplodedNode *N) const {
506 
507  if (!BT_msg_ret)
508  BT_msg_ret.reset(
509  new BuiltinBug(this, "Receiver in message expression is 'nil'"));
510 
511  const ObjCMessageExpr *ME = msg.getOriginExpr();
512 
513  QualType ResTy = msg.getResultType();
514 
515  SmallString<200> buf;
516  llvm::raw_svector_ostream os(buf);
517  os << "The receiver of message '";
518  ME->getSelector().print(os);
519  os << "' is nil";
520  if (ResTy->isReferenceType()) {
521  os << ", which results in forming a null reference";
522  } else {
523  os << " and returns a value of type '";
524  msg.getResultType().print(os, C.getLangOpts());
525  os << "' that will be garbage";
526  }
527 
528  auto report =
529  std::make_unique<PathSensitiveBugReport>(*BT_msg_ret, os.str(), N);
530  report->addRange(ME->getReceiverRange());
531  // FIXME: This won't track "self" in messages to super.
532  if (const Expr *receiver = ME->getInstanceReceiver()) {
533  bugreporter::trackExpressionValue(N, receiver, *report);
534  }
535  C.emitReport(std::move(report));
536 }
537 
538 static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
539  return (triple.getVendor() == llvm::Triple::Apple &&
540  (triple.isiOS() || triple.isWatchOS() ||
541  !triple.isMacOSXVersionLT(10,5)));
542 }
543 
544 void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
546  const ObjCMethodCall &Msg) const {
547  ASTContext &Ctx = C.getASTContext();
548  static CheckerProgramPointTag Tag(this, "NilReceiver");
549 
550  // Check the return type of the message expression. A message to nil will
551  // return different values depending on the return type and the architecture.
552  QualType RetTy = Msg.getResultType();
553  CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
554  const LocationContext *LCtx = C.getLocationContext();
555 
556  if (CanRetTy->isStructureOrClassType()) {
557  // Structure returns are safe since the compiler zeroes them out.
558  SVal V = C.getSValBuilder().makeZeroVal(RetTy);
559  C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
560  return;
561  }
562 
563  // Other cases: check if sizeof(return type) > sizeof(void*)
564  if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
565  .isConsumedExpr(Msg.getOriginExpr())) {
566  // Compute: sizeof(void *) and sizeof(return type)
567  const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
568  const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
569 
570  if (CanRetTy.getTypePtr()->isReferenceType()||
571  (voidPtrSize < returnTypeSize &&
573  (Ctx.FloatTy == CanRetTy ||
574  Ctx.DoubleTy == CanRetTy ||
575  Ctx.LongDoubleTy == CanRetTy ||
576  Ctx.LongLongTy == CanRetTy ||
577  Ctx.UnsignedLongLongTy == CanRetTy)))) {
578  if (ExplodedNode *N = C.generateErrorNode(state, &Tag))
579  emitNilReceiverBug(C, Msg, N);
580  return;
581  }
582 
583  // Handle the safe cases where the return value is 0 if the
584  // receiver is nil.
585  //
586  // FIXME: For now take the conservative approach that we only
587  // return null values if we *know* that the receiver is nil.
588  // This is because we can have surprises like:
589  //
590  // ... = [[NSScreens screens] objectAtIndex:0];
591  //
592  // What can happen is that [... screens] could return nil, but
593  // it most likely isn't nil. We should assume the semantics
594  // of this case unless we have *a lot* more knowledge.
595  //
596  SVal V = C.getSValBuilder().makeZeroVal(RetTy);
597  C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
598  return;
599  }
600 
601  C.addTransition(state);
602 }
603 
604 void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
605  mgr.registerChecker<CallAndMessageChecker>();
606 }
607 
608 bool ento::shouldRegisterCallAndMessageChecker(const LangOptions &LO) {
609  return true;
610 }
611 
612 void ento::registerCallAndMessageUnInitRefArg(CheckerManager &mgr) {
613  CallAndMessageChecker *Checker = mgr.getChecker<CallAndMessageChecker>();
614  Checker->Check_CallAndMessageUnInitRefArg = true;
615  Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckerName();
616 }
617 
618 bool ento::shouldRegisterCallAndMessageUnInitRefArg(const LangOptions &LO) {
619  return true;
620 }
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
Definition: CallEvent.cpp:977
CanQualType LongLongTy
Definition: ASTContext.h:1024
Represents a function declaration or definition.
Definition: Decl.h:1784
CanQualType VoidPtrTy
Definition: ASTContext.h:1043
A (possibly-)qualified type.
Definition: Type.h:643
Selector getSelector() const
Definition: ExprObjC.cpp:337
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:986
bool isArrayFormAsWritten() const
Definition: ExprCXX.h:2387
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:557
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:991
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
const RecordType * getAsStructureType() const
Definition: Type.cpp:573
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:706
for(auto typeArg :T->getTypeArgsAsWritten())
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
Definition: StoreRef.h:27
Represents a parameter to a function.
Definition: Decl.h:1600
Represents a struct/union/class.
Definition: Decl.h:3662
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
LineState State
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Definition: Decl.h:3867
field_range fields() const
Definition: Decl.h:3877
bool isReferenceType() const
Definition: Type.h:6403
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isGLValue() const
Definition: Expr.h:261
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:938
bool isSetter() const
Returns true if this property access or subscript is a setter (has the form of an assignment)...
Definition: CallEvent.h:1015
CanQualType LongDoubleTy
Definition: ASTContext.h:1027
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:83
Represents a non-static C++ member function call, no matter how it is written.
Definition: CallEvent.h:638
This represents one expression.
Definition: Expr.h:108
#define V(N, I)
Definition: ASTContext.h:2921
Expr * getCallee()
Definition: Expr.h:2638
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:950
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6207
Expr * getArgument()
Definition: ExprCXX.h:2401
CanQualType FloatTy
Definition: ASTContext.h:1027
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2348
CanQualType VoidTy
Definition: ASTContext.h:1015
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1260
virtual const ObjCMessageExpr * getOriginExpr() const
Definition: CallEvent.h:962
Dataflow Directional Tag Classes.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
Definition: ExprCXX.h:2359
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1026
ObjCMessageKind getMessageKind() const
Returns how the message was written in the source (property access, subscript, or explicit message se...
Definition: CallEvent.cpp:1037
SourceRange getReceiverRange() const
Source range of the receiver.
Definition: ExprObjC.cpp:321
static bool supportsNilWithFloatRet(const llvm::Triple &triple)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4444
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2088
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2289
static void describeUninitializedArgumentInCall(const CallEvent &Call, int ArgumentNumber, llvm::raw_svector_ostream &Os)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:262
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2521
bool isPointerType() const
Definition: Type.h:6391
QualType getType() const
Definition: Decl.h:655
A trivial tuple used to represent a source range.
CanQualType DoubleTy
Definition: ASTContext.h:1027
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2962