clang  5.0.0
StdLibraryFunctionsChecker.cpp
Go to the documentation of this file.
1 //=== StdLibraryFunctionsChecker.cpp - Model standard functions -*- 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 checker improves modeling of a few simple library functions.
11 // It does not generate warnings.
12 //
13 // This checker provides a specification format - `FunctionSummaryTy' - and
14 // contains descriptions of some library functions in this format. Each
15 // specification contains a list of branches for splitting the program state
16 // upon call, and range constraints on argument and return-value symbols that
17 // are satisfied on each branch. This spec can be expanded to include more
18 // items, like external effects of the function.
19 //
20 // The main difference between this approach and the body farms technique is
21 // in more explicit control over how many branches are produced. For example,
22 // consider standard C function `ispunct(int x)', which returns a non-zero value
23 // iff `x' is a punctuation character, that is, when `x' is in range
24 // ['!', '/'] [':', '@'] U ['[', '\`'] U ['{', '~'].
25 // `FunctionSummaryTy' provides only two branches for this function. However,
26 // any attempt to describe this range with if-statements in the body farm
27 // would result in many more branches. Because each branch needs to be analyzed
28 // independently, this significantly reduces performance. Additionally,
29 // once we consider a branch on which `x' is in range, say, ['!', '/'],
30 // we assume that such branch is an important separate path through the program,
31 // which may lead to false positives because considering this particular path
32 // was not consciously intended, and therefore it might have been unreachable.
33 //
34 // This checker uses eval::Call for modeling "pure" functions, for which
35 // their `FunctionSummaryTy' is a precise model. This avoids unnecessary
36 // invalidation passes. Conflicts with other checkers are unlikely because
37 // if the function has no other effects, other checkers would probably never
38 // want to improve upon the modeling done by this checker.
39 //
40 // Non-"pure" functions, for which only partial improvement over the default
41 // behavior is expected, are modeled via check::PostCall, non-intrusively.
42 //
43 // The following standard C functions are currently supported:
44 //
45 // fgetc getline isdigit isupper
46 // fread isalnum isgraph isxdigit
47 // fwrite isalpha islower read
48 // getc isascii isprint write
49 // getchar isblank ispunct
50 // getdelim iscntrl isspace
51 //
52 //===----------------------------------------------------------------------===//
53 
54 #include "ClangSACheckers.h"
59 
60 using namespace clang;
61 using namespace clang::ento;
62 
63 namespace {
64 class StdLibraryFunctionsChecker : public Checker<check::PostCall, eval::Call> {
65  /// Below is a series of typedefs necessary to define function specs.
66  /// We avoid nesting types here because each additional qualifier
67  /// would need to be repeated in every function spec.
68  struct FunctionSummaryTy;
69 
70  /// Specify how much the analyzer engine should entrust modeling this function
71  /// to us. If he doesn't, he performs additional invalidations.
72  enum InvalidationKindTy { NoEvalCall, EvalCallAsPure };
73 
74  /// A pair of ValueRangeKindTy and IntRangeVectorTy would describe a range
75  /// imposed on a particular argument or return value symbol.
76  ///
77  /// Given a range, should the argument stay inside or outside this range?
78  /// The special `ComparesToArgument' value indicates that we should
79  /// impose a constraint that involves other argument or return value symbols.
80  enum ValueRangeKindTy { OutOfRange, WithinRange, ComparesToArgument };
81 
82  // The universal integral type to use in value range descriptions.
83  // Unsigned to make sure overflows are well-defined.
84  typedef uint64_t RangeIntTy;
85 
86  /// Normally, describes a single range constraint, eg. {{0, 1}, {3, 4}} is
87  /// a non-negative integer, which less than 5 and not equal to 2. For
88  /// `ComparesToArgument', holds information about how exactly to compare to
89  /// the argument.
90  typedef std::vector<std::pair<RangeIntTy, RangeIntTy>> IntRangeVectorTy;
91 
92  /// A reference to an argument or return value by its number.
93  /// ArgNo in CallExpr and CallEvent is defined as Unsigned, but
94  /// obviously uint32_t should be enough for all practical purposes.
95  typedef uint32_t ArgNoTy;
96  static const ArgNoTy Ret = std::numeric_limits<ArgNoTy>::max();
97 
98  /// Incapsulates a single range on a single symbol within a branch.
99  class ValueRange {
100  ArgNoTy ArgNo; // Argument to which we apply the range.
101  ValueRangeKindTy Kind; // Kind of range definition.
102  IntRangeVectorTy Args; // Polymorphic arguments.
103 
104  public:
105  ValueRange(ArgNoTy ArgNo, ValueRangeKindTy Kind,
106  const IntRangeVectorTy &Args)
107  : ArgNo(ArgNo), Kind(Kind), Args(Args) {}
108 
109  ArgNoTy getArgNo() const { return ArgNo; }
110  ValueRangeKindTy getKind() const { return Kind; }
111 
113  assert(Kind == ComparesToArgument);
114  assert(Args.size() == 1);
116  static_cast<BinaryOperator::Opcode>(Args[0].first);
117  assert(BinaryOperator::isComparisonOp(Op) &&
118  "Only comparison ops are supported for ComparesToArgument");
119  return Op;
120  }
121 
122  ArgNoTy getOtherArgNo() const {
123  assert(Kind == ComparesToArgument);
124  assert(Args.size() == 1);
125  return static_cast<ArgNoTy>(Args[0].second);
126  }
127 
128  const IntRangeVectorTy &getRanges() const {
129  assert(Kind != ComparesToArgument);
130  return Args;
131  }
132 
133  // We avoid creating a virtual apply() method because
134  // it makes initializer lists harder to write.
135  private:
137  applyAsOutOfRange(ProgramStateRef State, const CallEvent &Call,
138  const FunctionSummaryTy &Summary) const;
140  applyAsWithinRange(ProgramStateRef State, const CallEvent &Call,
141  const FunctionSummaryTy &Summary) const;
143  applyAsComparesToArgument(ProgramStateRef State, const CallEvent &Call,
144  const FunctionSummaryTy &Summary) const;
145 
146  public:
147  ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
148  const FunctionSummaryTy &Summary) const {
149  switch (Kind) {
150  case OutOfRange:
151  return applyAsOutOfRange(State, Call, Summary);
152  case WithinRange:
153  return applyAsWithinRange(State, Call, Summary);
154  case ComparesToArgument:
155  return applyAsComparesToArgument(State, Call, Summary);
156  }
157  llvm_unreachable("Unknown ValueRange kind!");
158  }
159  };
160 
161  /// The complete list of ranges that defines a single branch.
162  typedef std::vector<ValueRange> ValueRangeSet;
163 
164  /// Includes information about function prototype (which is necessary to
165  /// ensure we're modeling the right function and casting values properly),
166  /// approach to invalidation, and a list of branches - essentially, a list
167  /// of list of ranges - essentially, a list of lists of lists of segments.
168  struct FunctionSummaryTy {
169  const std::vector<QualType> ArgTypes;
170  const QualType RetType;
171  const InvalidationKindTy InvalidationKind;
172  const std::vector<ValueRangeSet> Ranges;
173 
174  private:
175  static void assertTypeSuitableForSummary(QualType T) {
176  assert(!T->isVoidType() &&
177  "We should have had no significant void types in the spec");
178  assert(T.isCanonical() &&
179  "We should only have canonical types in the spec");
180  // FIXME: lift this assert (but not the ones above!)
181  assert(T->isIntegralOrEnumerationType() &&
182  "We only support integral ranges in the spec");
183  }
184 
185  public:
186  QualType getArgType(ArgNoTy ArgNo) const {
187  QualType T = (ArgNo == Ret) ? RetType : ArgTypes[ArgNo];
188  assertTypeSuitableForSummary(T);
189  return T;
190  }
191 
192  /// Try our best to figure out if the call expression is the call of
193  /// *the* library function to which this specification applies.
194  bool matchesCall(const CallExpr *CE) const;
195  };
196 
197  // The same function (as in, function identifier) may have different
198  // summaries assigned to it, with different argument and return value types.
199  // We call these "variants" of the function. This can be useful for handling
200  // C++ function overloads, and also it can be used when the same function
201  // may have different definitions on different platforms.
202  typedef std::vector<FunctionSummaryTy> FunctionVariantsTy;
203 
204  // The map of all functions supported by the checker. It is initialized
205  // lazily, and it doesn't change after initialization.
206  typedef llvm::StringMap<FunctionVariantsTy> FunctionSummaryMapTy;
207  mutable FunctionSummaryMapTy FunctionSummaryMap;
208 
209  // Auxiliary functions to support ArgNoTy within all structures
210  // in a unified manner.
211  static QualType getArgType(const FunctionSummaryTy &Summary, ArgNoTy ArgNo) {
212  return Summary.getArgType(ArgNo);
213  }
214  static QualType getArgType(const CallEvent &Call, ArgNoTy ArgNo) {
215  return ArgNo == Ret ? Call.getResultType().getCanonicalType()
216  : Call.getArgExpr(ArgNo)->getType().getCanonicalType();
217  }
218  static QualType getArgType(const CallExpr *CE, ArgNoTy ArgNo) {
219  return ArgNo == Ret ? CE->getType().getCanonicalType()
220  : CE->getArg(ArgNo)->getType().getCanonicalType();
221  }
222  static SVal getArgSVal(const CallEvent &Call, ArgNoTy ArgNo) {
223  return ArgNo == Ret ? Call.getReturnValue() : Call.getArgSVal(ArgNo);
224  }
225 
226 public:
227  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
228  bool evalCall(const CallExpr *CE, CheckerContext &C) const;
229 
230 private:
231  Optional<FunctionSummaryTy> findFunctionSummary(const FunctionDecl *FD,
232  const CallExpr *CE,
233  CheckerContext &C) const;
234 
235  void initFunctionSummaries(BasicValueFactory &BVF) const;
236 };
237 } // end of anonymous namespace
238 
239 ProgramStateRef StdLibraryFunctionsChecker::ValueRange::applyAsOutOfRange(
240  ProgramStateRef State, const CallEvent &Call,
241  const FunctionSummaryTy &Summary) const {
242 
243  ProgramStateManager &Mgr = State->getStateManager();
244  SValBuilder &SVB = Mgr.getSValBuilder();
247  QualType T = getArgType(Summary, getArgNo());
248  SVal V = getArgSVal(Call, getArgNo());
249 
250  if (auto N = V.getAs<NonLoc>()) {
251  const IntRangeVectorTy &R = getRanges();
252  size_t E = R.size();
253  for (size_t I = 0; I != E; ++I) {
254  const llvm::APSInt &Min = BVF.getValue(R[I].first, T);
255  const llvm::APSInt &Max = BVF.getValue(R[I].second, T);
256  assert(Min <= Max);
257  State = CM.assumeInclusiveRange(State, *N, Min, Max, false);
258  if (!State)
259  break;
260  }
261  }
262 
263  return State;
264 }
265 
267 StdLibraryFunctionsChecker::ValueRange::applyAsWithinRange(
268  ProgramStateRef State, const CallEvent &Call,
269  const FunctionSummaryTy &Summary) const {
270 
271  ProgramStateManager &Mgr = State->getStateManager();
272  SValBuilder &SVB = Mgr.getSValBuilder();
275  QualType T = getArgType(Summary, getArgNo());
276  SVal V = getArgSVal(Call, getArgNo());
277 
278  // "WithinRange R" is treated as "outside [T_MIN, T_MAX] \ R".
279  // We cut off [T_MIN, min(R) - 1] and [max(R) + 1, T_MAX] if necessary,
280  // and then cut away all holes in R one by one.
281  if (auto N = V.getAs<NonLoc>()) {
282  const IntRangeVectorTy &R = getRanges();
283  size_t E = R.size();
284 
285  const llvm::APSInt &MinusInf = BVF.getMinValue(T);
286  const llvm::APSInt &PlusInf = BVF.getMaxValue(T);
287 
288  const llvm::APSInt &Left = BVF.getValue(R[0].first - 1ULL, T);
289  if (Left != PlusInf) {
290  assert(MinusInf <= Left);
291  State = CM.assumeInclusiveRange(State, *N, MinusInf, Left, false);
292  if (!State)
293  return nullptr;
294  }
295 
296  const llvm::APSInt &Right = BVF.getValue(R[E - 1].second + 1ULL, T);
297  if (Right != MinusInf) {
298  assert(Right <= PlusInf);
299  State = CM.assumeInclusiveRange(State, *N, Right, PlusInf, false);
300  if (!State)
301  return nullptr;
302  }
303 
304  for (size_t I = 1; I != E; ++I) {
305  const llvm::APSInt &Min = BVF.getValue(R[I - 1].second + 1ULL, T);
306  const llvm::APSInt &Max = BVF.getValue(R[I].first - 1ULL, T);
307  assert(Min <= Max);
308  State = CM.assumeInclusiveRange(State, *N, Min, Max, false);
309  if (!State)
310  return nullptr;
311  }
312  }
313 
314  return State;
315 }
316 
318 StdLibraryFunctionsChecker::ValueRange::applyAsComparesToArgument(
319  ProgramStateRef State, const CallEvent &Call,
320  const FunctionSummaryTy &Summary) const {
321 
322  ProgramStateManager &Mgr = State->getStateManager();
323  SValBuilder &SVB = Mgr.getSValBuilder();
324  QualType CondT = SVB.getConditionType();
325  QualType T = getArgType(Summary, getArgNo());
326  SVal V = getArgSVal(Call, getArgNo());
327 
329  ArgNoTy OtherArg = getOtherArgNo();
330  SVal OtherV = getArgSVal(Call, OtherArg);
331  QualType OtherT = getArgType(Call, OtherArg);
332  // Note: we avoid integral promotion for comparison.
333  OtherV = SVB.evalCast(OtherV, T, OtherT);
334  if (auto CompV = SVB.evalBinOp(State, Op, V, OtherV, CondT)
336  State = State->assume(*CompV, true);
337  return State;
338 }
339 
340 void StdLibraryFunctionsChecker::checkPostCall(const CallEvent &Call,
341  CheckerContext &C) const {
342  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
343  if (!FD)
344  return;
345 
346  const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
347  if (!CE)
348  return;
349 
350  Optional<FunctionSummaryTy> FoundSummary = findFunctionSummary(FD, CE, C);
351  if (!FoundSummary)
352  return;
353 
354  // Now apply ranges.
355  const FunctionSummaryTy &Summary = *FoundSummary;
356  ProgramStateRef State = C.getState();
357 
358  for (const auto &VRS: Summary.Ranges) {
359  ProgramStateRef NewState = State;
360  for (const auto &VR: VRS) {
361  NewState = VR.apply(NewState, Call, Summary);
362  if (!NewState)
363  break;
364  }
365 
366  if (NewState && NewState != State)
367  C.addTransition(NewState);
368  }
369 }
370 
371 bool StdLibraryFunctionsChecker::evalCall(const CallExpr *CE,
372  CheckerContext &C) const {
373  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl());
374  if (!FD)
375  return false;
376 
377  Optional<FunctionSummaryTy> FoundSummary = findFunctionSummary(FD, CE, C);
378  if (!FoundSummary)
379  return false;
380 
381  const FunctionSummaryTy &Summary = *FoundSummary;
382  switch (Summary.InvalidationKind) {
383  case EvalCallAsPure: {
384  ProgramStateRef State = C.getState();
385  const LocationContext *LC = C.getLocationContext();
387  CE, LC, CE->getType().getCanonicalType(), C.blockCount());
388  State = State->BindExpr(CE, LC, V);
389  C.addTransition(State);
390  return true;
391  }
392  case NoEvalCall:
393  // Summary tells us to avoid performing eval::Call. The function is possibly
394  // evaluated by another checker, or evaluated conservatively.
395  return false;
396  }
397  llvm_unreachable("Unknown invalidation kind!");
398 }
399 
400 bool StdLibraryFunctionsChecker::FunctionSummaryTy::matchesCall(
401  const CallExpr *CE) const {
402  // Check number of arguments:
403  if (CE->getNumArgs() != ArgTypes.size())
404  return false;
405 
406  // Check return type if relevant:
407  if (!RetType.isNull() && RetType != CE->getType().getCanonicalType())
408  return false;
409 
410  // Check argument types when relevant:
411  for (size_t I = 0, E = ArgTypes.size(); I != E; ++I) {
412  QualType FormalT = ArgTypes[I];
413  // Null type marks irrelevant arguments.
414  if (FormalT.isNull())
415  continue;
416 
417  assertTypeSuitableForSummary(FormalT);
418 
419  QualType ActualT = StdLibraryFunctionsChecker::getArgType(CE, I);
420  assert(ActualT.isCanonical());
421  if (ActualT != FormalT)
422  return false;
423  }
424 
425  return true;
426 }
427 
429 StdLibraryFunctionsChecker::findFunctionSummary(const FunctionDecl *FD,
430  const CallExpr *CE,
431  CheckerContext &C) const {
432  // Note: we cannot always obtain FD from CE
433  // (eg. virtual call, or call by pointer).
434  assert(CE);
435 
436  if (!FD)
437  return None;
438 
439  SValBuilder &SVB = C.getSValBuilder();
441  initFunctionSummaries(BVF);
442 
443  IdentifierInfo *II = FD->getIdentifier();
444  if (!II)
445  return None;
446  StringRef Name = II->getName();
447  if (Name.empty() || !C.isCLibraryFunction(FD, Name))
448  return None;
449 
450  auto FSMI = FunctionSummaryMap.find(Name);
451  if (FSMI == FunctionSummaryMap.end())
452  return None;
453 
454  // Verify that function signature matches the spec in advance.
455  // Otherwise we might be modeling the wrong function.
456  // Strict checking is important because we will be conducting
457  // very integral-type-sensitive operations on arguments and
458  // return values.
459  const FunctionVariantsTy &SpecVariants = FSMI->second;
460  for (const FunctionSummaryTy &Spec : SpecVariants)
461  if (Spec.matchesCall(CE))
462  return Spec;
463 
464  return None;
465 }
466 
467 void StdLibraryFunctionsChecker::initFunctionSummaries(
468  BasicValueFactory &BVF) const {
469  if (!FunctionSummaryMap.empty())
470  return;
471 
472  ASTContext &ACtx = BVF.getContext();
473 
474  // These types are useful for writing specifications quickly,
475  // New specifications should probably introduce more types.
476  // Some types are hard to obtain from the AST, eg. "ssize_t".
477  // In such cases it should be possible to provide multiple variants
478  // of function summary for common cases (eg. ssize_t could be int or long
479  // or long long, so three summary variants would be enough).
480  // Of course, function variants are also useful for C++ overloads.
481  QualType Irrelevant; // A placeholder, whenever we do not care about the type.
482  QualType IntTy = ACtx.IntTy;
483  QualType LongTy = ACtx.LongTy;
484  QualType LongLongTy = ACtx.LongLongTy;
485  QualType SizeTy = ACtx.getSizeType();
486 
487  RangeIntTy IntMax = BVF.getMaxValue(IntTy).getLimitedValue();
488  RangeIntTy LongMax = BVF.getMaxValue(LongTy).getLimitedValue();
489  RangeIntTy LongLongMax = BVF.getMaxValue(LongLongTy).getLimitedValue();
490 
491  // We are finally ready to define specifications for all supported functions.
492  //
493  // The signature needs to have the correct number of arguments.
494  // However, we insert `Irrelevant' when the type is insignificant.
495  //
496  // Argument ranges should always cover all variants. If return value
497  // is completely unknown, omit it from the respective range set.
498  //
499  // All types in the spec need to be canonical.
500  //
501  // Every item in the list of range sets represents a particular
502  // execution path the analyzer would need to explore once
503  // the call is modeled - a new program state is constructed
504  // for every range set, and each range line in the range set
505  // corresponds to a specific constraint within this state.
506  //
507  // Upon comparing to another argument, the other argument is casted
508  // to the current argument's type. This avoids proper promotion but
509  // seems useful. For example, read() receives size_t argument,
510  // and its return value, which is of type ssize_t, cannot be greater
511  // than this argument. If we made a promotion, and the size argument
512  // is equal to, say, 10, then we'd impose a range of [0, 10] on the
513  // return value, however the correct range is [-1, 10].
514  //
515  // Please update the list of functions in the header after editing!
516  //
517  // The format is as follows:
518  //
519  //{ "function name",
520  // { spec:
521  // { argument types list, ... },
522  // return type, purity, { range set list:
523  // { range list:
524  // { argument index, within or out of, {{from, to}, ...} },
525  // { argument index, compares to argument, {{how, which}} },
526  // ...
527  // }
528  // }
529  // }
530  //}
531 
532 #define SUMMARY_WITH_VARIANTS(identifier) {#identifier, {
533 #define END_SUMMARY_WITH_VARIANTS }},
534 #define VARIANT(argument_types, return_type, invalidation_approach) \
535  { argument_types, return_type, invalidation_approach, {
536 #define END_VARIANT } },
537 #define SUMMARY(identifier, argument_types, return_type, \
538  invalidation_approach) \
539  { #identifier, { { argument_types, return_type, invalidation_approach, {
540 #define END_SUMMARY } } } },
541 #define ARGUMENT_TYPES(...) { __VA_ARGS__ }
542 #define RETURN_TYPE(x) x
543 #define INVALIDATION_APPROACH(x) x
544 #define CASE {
545 #define END_CASE },
546 #define ARGUMENT_CONDITION(argument_number, condition_kind) \
547  { argument_number, condition_kind, {
548 #define END_ARGUMENT_CONDITION }},
549 #define RETURN_VALUE_CONDITION(condition_kind) \
550  { Ret, condition_kind, {
551 #define END_RETURN_VALUE_CONDITION }},
552 #define ARG_NO(x) x##U
553 #define RANGE(x, y) { x, y },
554 #define SINGLE_VALUE(x) RANGE(x, x)
555 #define IS_LESS_THAN(arg) { BO_LE, arg }
556 
557  FunctionSummaryMap = {
558  // The isascii() family of functions.
559  SUMMARY(isalnum, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
560  INVALIDATION_APPROACH(EvalCallAsPure))
561  CASE // Boils down to isupper() or islower() or isdigit()
562  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
563  RANGE('0', '9')
564  RANGE('A', 'Z')
565  RANGE('a', 'z')
567  RETURN_VALUE_CONDITION(OutOfRange)
568  SINGLE_VALUE(0)
570  END_CASE
571  CASE // The locale-specific range.
572  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
573  RANGE(128, 255)
575  // No post-condition. We are completely unaware of
576  // locale-specific return values.
577  END_CASE
578  CASE
579  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
580  RANGE('0', '9')
581  RANGE('A', 'Z')
582  RANGE('a', 'z')
583  RANGE(128, 255)
585  RETURN_VALUE_CONDITION(WithinRange)
586  SINGLE_VALUE(0)
588  END_CASE
590  SUMMARY(isalpha, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
591  INVALIDATION_APPROACH(EvalCallAsPure))
592  CASE // isupper() or islower(). Note that 'Z' is less than 'a'.
593  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
594  RANGE('A', 'Z')
595  RANGE('a', 'z')
597  RETURN_VALUE_CONDITION(OutOfRange)
598  SINGLE_VALUE(0)
600  END_CASE
601  CASE // The locale-specific range.
602  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
603  RANGE(128, 255)
605  END_CASE
606  CASE // Other.
607  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
608  RANGE('A', 'Z')
609  RANGE('a', 'z')
610  RANGE(128, 255)
612  RETURN_VALUE_CONDITION(WithinRange)
613  SINGLE_VALUE(0)
615  END_CASE
617  SUMMARY(isascii, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
618  INVALIDATION_APPROACH(EvalCallAsPure))
619  CASE // Is ASCII.
620  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
621  RANGE(0, 127)
623  RETURN_VALUE_CONDITION(OutOfRange)
624  SINGLE_VALUE(0)
626  END_CASE
627  CASE
628  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
629  RANGE(0, 127)
631  RETURN_VALUE_CONDITION(WithinRange)
632  SINGLE_VALUE(0)
634  END_CASE
636  SUMMARY(isblank, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
637  INVALIDATION_APPROACH(EvalCallAsPure))
638  CASE
639  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
640  SINGLE_VALUE('\t')
641  SINGLE_VALUE(' ')
643  RETURN_VALUE_CONDITION(OutOfRange)
644  SINGLE_VALUE(0)
646  END_CASE
647  CASE
648  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
649  SINGLE_VALUE('\t')
650  SINGLE_VALUE(' ')
652  RETURN_VALUE_CONDITION(WithinRange)
653  SINGLE_VALUE(0)
655  END_CASE
657  SUMMARY(iscntrl, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
658  INVALIDATION_APPROACH(EvalCallAsPure))
659  CASE // 0..31 or 127
660  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
661  RANGE(0, 32)
662  SINGLE_VALUE(127)
664  RETURN_VALUE_CONDITION(OutOfRange)
665  SINGLE_VALUE(0)
667  END_CASE
668  CASE
669  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
670  RANGE(0, 32)
671  SINGLE_VALUE(127)
673  RETURN_VALUE_CONDITION(WithinRange)
674  SINGLE_VALUE(0)
676  END_CASE
678  SUMMARY(isdigit, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
679  INVALIDATION_APPROACH(EvalCallAsPure))
680  CASE // Is a digit.
681  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
682  RANGE('0', '9')
684  RETURN_VALUE_CONDITION(OutOfRange)
685  SINGLE_VALUE(0)
687  END_CASE
688  CASE
689  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
690  RANGE('0', '9')
692  RETURN_VALUE_CONDITION(WithinRange)
693  SINGLE_VALUE(0)
695  END_CASE
697  SUMMARY(isgraph, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
698  INVALIDATION_APPROACH(EvalCallAsPure))
699  CASE
700  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
701  RANGE(33, 126)
703  RETURN_VALUE_CONDITION(OutOfRange)
704  SINGLE_VALUE(0)
706  END_CASE
707  CASE
708  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
709  RANGE(33, 126)
711  RETURN_VALUE_CONDITION(WithinRange)
712  SINGLE_VALUE(0)
714  END_CASE
716  SUMMARY(islower, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
717  INVALIDATION_APPROACH(EvalCallAsPure))
718  CASE // Is certainly lowercase.
719  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
720  RANGE('a', 'z')
722  RETURN_VALUE_CONDITION(OutOfRange)
723  SINGLE_VALUE(0)
725  END_CASE
726  CASE // Is ascii but not lowercase.
727  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
728  RANGE(0, 127)
730  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
731  RANGE('a', 'z')
733  RETURN_VALUE_CONDITION(WithinRange)
734  SINGLE_VALUE(0)
736  END_CASE
737  CASE // The locale-specific range.
738  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
739  RANGE(128, 255)
741  END_CASE
742  CASE // Is not an unsigned char.
743  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
744  RANGE(0, 255)
746  RETURN_VALUE_CONDITION(WithinRange)
747  SINGLE_VALUE(0)
749  END_CASE
751  SUMMARY(isprint, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
752  INVALIDATION_APPROACH(EvalCallAsPure))
753  CASE
754  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
755  RANGE(32, 126)
757  RETURN_VALUE_CONDITION(OutOfRange)
758  SINGLE_VALUE(0)
760  END_CASE
761  CASE
762  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
763  RANGE(32, 126)
765  RETURN_VALUE_CONDITION(WithinRange)
766  SINGLE_VALUE(0)
768  END_CASE
770  SUMMARY(ispunct, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
771  INVALIDATION_APPROACH(EvalCallAsPure))
772  CASE
773  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
774  RANGE('!', '/')
775  RANGE(':', '@')
776  RANGE('[', '`')
777  RANGE('{', '~')
778  END_ARGUMENT_CONDITION
779  RETURN_VALUE_CONDITION(OutOfRange)
780  SINGLE_VALUE(0)
781  END_RETURN_VALUE_CONDITION
782  END_CASE
783  CASE
784  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
785  RANGE('!', '/')
786  RANGE(':', '@')
787  RANGE('[', '`')
788  RANGE('{', '~')
789  END_ARGUMENT_CONDITION
790  RETURN_VALUE_CONDITION(WithinRange)
791  SINGLE_VALUE(0)
792  END_RETURN_VALUE_CONDITION
793  END_CASE
794  END_SUMMARY
795  SUMMARY(isspace, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
796  INVALIDATION_APPROACH(EvalCallAsPure))
797  CASE // Space, '\f', '\n', '\r', '\t', '\v'.
798  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
799  RANGE(9, 13)
800  SINGLE_VALUE(' ')
801  END_ARGUMENT_CONDITION
802  RETURN_VALUE_CONDITION(OutOfRange)
803  SINGLE_VALUE(0)
804  END_RETURN_VALUE_CONDITION
805  END_CASE
806  CASE // The locale-specific range.
807  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
808  RANGE(128, 255)
809  END_ARGUMENT_CONDITION
810  END_CASE
811  CASE
812  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
813  RANGE(9, 13)
814  SINGLE_VALUE(' ')
815  RANGE(128, 255)
816  END_ARGUMENT_CONDITION
817  RETURN_VALUE_CONDITION(WithinRange)
818  SINGLE_VALUE(0)
819  END_RETURN_VALUE_CONDITION
820  END_CASE
821  END_SUMMARY
822  SUMMARY(isupper, ARGUMENT_TYPES(IntTy), RETURN_TYPE (IntTy),
823  INVALIDATION_APPROACH(EvalCallAsPure))
824  CASE // Is certainly uppercase.
825  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
826  RANGE('A', 'Z')
827  END_ARGUMENT_CONDITION
828  RETURN_VALUE_CONDITION(OutOfRange)
829  SINGLE_VALUE(0)
830  END_RETURN_VALUE_CONDITION
831  END_CASE
832  CASE // The locale-specific range.
833  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
834  RANGE(128, 255)
835  END_ARGUMENT_CONDITION
836  END_CASE
837  CASE // Other.
838  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
839  RANGE('A', 'Z') RANGE(128, 255)
840  END_ARGUMENT_CONDITION
841  RETURN_VALUE_CONDITION(WithinRange)
842  SINGLE_VALUE(0)
843  END_RETURN_VALUE_CONDITION
844  END_CASE
845  END_SUMMARY
846  SUMMARY(isxdigit, ARGUMENT_TYPES(IntTy), RETURN_TYPE(IntTy),
847  INVALIDATION_APPROACH(EvalCallAsPure))
848  CASE
849  ARGUMENT_CONDITION(ARG_NO(0), WithinRange)
850  RANGE('0', '9')
851  RANGE('A', 'F')
852  RANGE('a', 'f')
853  END_ARGUMENT_CONDITION
854  RETURN_VALUE_CONDITION(OutOfRange)
855  SINGLE_VALUE(0)
856  END_RETURN_VALUE_CONDITION
857  END_CASE
858  CASE
859  ARGUMENT_CONDITION(ARG_NO(0), OutOfRange)
860  RANGE('0', '9')
861  RANGE('A', 'F')
862  RANGE('a', 'f')
863  END_ARGUMENT_CONDITION
864  RETURN_VALUE_CONDITION(WithinRange)
865  SINGLE_VALUE(0)
866  END_RETURN_VALUE_CONDITION
867  END_CASE
868  END_SUMMARY
869 
870  // The getc() family of functions that returns either a char or an EOF.
871  SUMMARY(getc, ARGUMENT_TYPES(Irrelevant), RETURN_TYPE(IntTy),
872  INVALIDATION_APPROACH(NoEvalCall))
873  CASE // FIXME: EOF is assumed to be defined as -1.
874  RETURN_VALUE_CONDITION(WithinRange)
875  RANGE(-1, 255)
876  END_RETURN_VALUE_CONDITION
877  END_CASE
878  END_SUMMARY
879  SUMMARY(fgetc, ARGUMENT_TYPES(Irrelevant), RETURN_TYPE(IntTy),
880  INVALIDATION_APPROACH(NoEvalCall))
881  CASE // FIXME: EOF is assumed to be defined as -1.
882  RETURN_VALUE_CONDITION(WithinRange)
883  RANGE(-1, 255)
884  END_RETURN_VALUE_CONDITION
885  END_CASE
886  END_SUMMARY
887  SUMMARY(getchar, ARGUMENT_TYPES(), RETURN_TYPE(IntTy),
888  INVALIDATION_APPROACH(NoEvalCall))
889  CASE // FIXME: EOF is assumed to be defined as -1.
890  RETURN_VALUE_CONDITION(WithinRange)
891  RANGE(-1, 255)
892  END_RETURN_VALUE_CONDITION
893  END_CASE
894  END_SUMMARY
895 
896  // read()-like functions that never return more than buffer size.
897  // We are not sure how ssize_t is defined on every platform, so we provide
898  // three variants that should cover common cases.
899  SUMMARY_WITH_VARIANTS(read)
900  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
901  RETURN_TYPE(IntTy), INVALIDATION_APPROACH(NoEvalCall))
902  CASE
903  RETURN_VALUE_CONDITION(ComparesToArgument)
904  IS_LESS_THAN(ARG_NO(2))
905  END_RETURN_VALUE_CONDITION
906  RETURN_VALUE_CONDITION(WithinRange)
907  RANGE(-1, IntMax)
908  END_RETURN_VALUE_CONDITION
909  END_CASE
910  END_VARIANT
911  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
912  RETURN_TYPE(LongTy), INVALIDATION_APPROACH(NoEvalCall))
913  CASE
914  RETURN_VALUE_CONDITION(ComparesToArgument)
915  IS_LESS_THAN(ARG_NO(2))
916  END_RETURN_VALUE_CONDITION
917  RETURN_VALUE_CONDITION(WithinRange)
918  RANGE(-1, LongMax)
919  END_RETURN_VALUE_CONDITION
920  END_CASE
921  END_VARIANT
922  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
923  RETURN_TYPE(LongLongTy), INVALIDATION_APPROACH(NoEvalCall))
924  CASE
925  RETURN_VALUE_CONDITION(ComparesToArgument)
926  IS_LESS_THAN(ARG_NO(2))
927  END_RETURN_VALUE_CONDITION
928  RETURN_VALUE_CONDITION(WithinRange)
929  RANGE(-1, LongLongMax)
930  END_RETURN_VALUE_CONDITION
931  END_CASE
932  END_VARIANT
933  END_SUMMARY_WITH_VARIANTS
934  SUMMARY_WITH_VARIANTS(write)
935  // Again, due to elusive nature of ssize_t, we have duplicate
936  // our summaries to cover different variants.
937  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
938  RETURN_TYPE(IntTy), INVALIDATION_APPROACH(NoEvalCall))
939  CASE
940  RETURN_VALUE_CONDITION(ComparesToArgument)
941  IS_LESS_THAN(ARG_NO(2))
942  END_RETURN_VALUE_CONDITION
943  RETURN_VALUE_CONDITION(WithinRange)
944  RANGE(-1, IntMax)
945  END_RETURN_VALUE_CONDITION
946  END_CASE
947  END_VARIANT
948  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
949  RETURN_TYPE(LongTy), INVALIDATION_APPROACH(NoEvalCall))
950  CASE
951  RETURN_VALUE_CONDITION(ComparesToArgument)
952  IS_LESS_THAN(ARG_NO(2))
953  END_RETURN_VALUE_CONDITION
954  RETURN_VALUE_CONDITION(WithinRange)
955  RANGE(-1, LongMax)
956  END_RETURN_VALUE_CONDITION
957  END_CASE
958  END_VARIANT
959  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy),
960  RETURN_TYPE(LongLongTy), INVALIDATION_APPROACH(NoEvalCall))
961  CASE
962  RETURN_VALUE_CONDITION(ComparesToArgument)
963  IS_LESS_THAN(ARG_NO(2))
964  END_RETURN_VALUE_CONDITION
965  RETURN_VALUE_CONDITION(WithinRange)
966  RANGE(-1, LongLongMax)
967  END_RETURN_VALUE_CONDITION
968  END_CASE
969  END_VARIANT
970  END_SUMMARY_WITH_VARIANTS
971  SUMMARY(fread,
972  ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy, Irrelevant),
973  RETURN_TYPE(SizeTy), INVALIDATION_APPROACH(NoEvalCall))
974  CASE
975  RETURN_VALUE_CONDITION(ComparesToArgument)
976  IS_LESS_THAN(ARG_NO(2))
977  END_RETURN_VALUE_CONDITION
978  END_CASE
979  END_SUMMARY
980  SUMMARY(fwrite,
981  ARGUMENT_TYPES(Irrelevant, Irrelevant, SizeTy, Irrelevant),
982  RETURN_TYPE(SizeTy), INVALIDATION_APPROACH(NoEvalCall))
983  CASE
984  RETURN_VALUE_CONDITION(ComparesToArgument)
985  IS_LESS_THAN(ARG_NO(2))
986  END_RETURN_VALUE_CONDITION
987  END_CASE
988  END_SUMMARY
989 
990  // getline()-like functions either fail or read at least the delimiter.
991  SUMMARY_WITH_VARIANTS(getline)
992  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant),
993  RETURN_TYPE(IntTy), INVALIDATION_APPROACH(NoEvalCall))
994  CASE
995  RETURN_VALUE_CONDITION(WithinRange)
996  SINGLE_VALUE(-1)
997  RANGE(1, IntMax)
998  END_RETURN_VALUE_CONDITION
999  END_CASE
1000  END_VARIANT
1001  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant),
1002  RETURN_TYPE(LongTy), INVALIDATION_APPROACH(NoEvalCall))
1003  CASE
1004  RETURN_VALUE_CONDITION(WithinRange)
1005  SINGLE_VALUE(-1)
1006  RANGE(1, LongMax)
1007  END_RETURN_VALUE_CONDITION
1008  END_CASE
1009  END_VARIANT
1010  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant),
1011  RETURN_TYPE(LongLongTy), INVALIDATION_APPROACH(NoEvalCall))
1012  CASE
1013  RETURN_VALUE_CONDITION(WithinRange)
1014  SINGLE_VALUE(-1)
1015  RANGE(1, LongLongMax)
1016  END_RETURN_VALUE_CONDITION
1017  END_CASE
1018  END_VARIANT
1019  END_SUMMARY_WITH_VARIANTS
1020  SUMMARY_WITH_VARIANTS(getdelim)
1021  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant, Irrelevant),
1022  RETURN_TYPE(IntTy), INVALIDATION_APPROACH(NoEvalCall))
1023  CASE
1024  RETURN_VALUE_CONDITION(WithinRange)
1025  SINGLE_VALUE(-1)
1026  RANGE(1, IntMax)
1027  END_RETURN_VALUE_CONDITION
1028  END_CASE
1029  END_VARIANT
1030  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant, Irrelevant),
1031  RETURN_TYPE(LongTy), INVALIDATION_APPROACH(NoEvalCall))
1032  CASE
1033  RETURN_VALUE_CONDITION(WithinRange)
1034  SINGLE_VALUE(-1)
1035  RANGE(1, LongMax)
1036  END_RETURN_VALUE_CONDITION
1037  END_CASE
1038  END_VARIANT
1039  VARIANT(ARGUMENT_TYPES(Irrelevant, Irrelevant, Irrelevant, Irrelevant),
1040  RETURN_TYPE(LongLongTy), INVALIDATION_APPROACH(NoEvalCall))
1041  CASE
1042  RETURN_VALUE_CONDITION(WithinRange)
1043  SINGLE_VALUE(-1)
1044  RANGE(1, LongLongMax)
1045  END_RETURN_VALUE_CONDITION
1046  END_CASE
1047  END_VARIANT
1048  END_SUMMARY_WITH_VARIANTS
1049  };
1050 }
1051 
1052 void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
1053  // If this checker grows large enough to support C++, Objective-C, or other
1054  // standard libraries, we could use multiple register...Checker() functions,
1055  // which would register various checkers with the help of the same Checker
1056  // class, turning on different function summaries.
1057  mgr.registerChecker<StdLibraryFunctionsChecker>();
1058 }
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
Definition: CallEvent.cpp:226
CanQualType LongLongTy
Definition: ASTContext.h:971
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1618
A (possibly-)qualified type.
Definition: Type.h:616
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2275
#define END_CASE
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:232
#define RETURN_TYPE(x)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
CanQualType LongTy
Definition: ASTContext.h:971
SVal evalCast(SVal val, QualType castTy, QualType originalType)
bool isCanonical() const
Definition: Type.h:5533
ASTContext & getContext() const
bool isVoidType() const
Definition: Type.h:5906
bool isComparisonOp() const
Definition: Expr.h:3058
#define END_SUMMARY
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
LineState State
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition: CallEvent.h:225
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
BinaryOperatorKind
#define END_RETURN_VALUE_CONDITION
detail::InMemoryDirectory::const_iterator I
#define SUMMARY(identifier, argument_types, return_type,invalidation_approach)
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument.
Definition: CallEvent.h:275
StringRef getName() const
Return the actual identifier string.
const ProgramStateRef & getState() const
#define RETURN_VALUE_CONDITION(condition_kind)
#define ARG_NO(x)
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the callee is an externally-visible function in the top-level namespace, such as malloc.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:100
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
QualType getConditionType() const
Definition: SValBuilder.h:136
do v
Definition: arm_acle.h:78
virtual ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, const llvm::APSInt &To, bool InBound)=0
#define RANGE(x, y)
Kind
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:5956
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
#define SINGLE_VALUE(x)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
#define ARGUMENT_CONDITION(argument_number, condition_kind)
#define ARGUMENT_TYPES(...)
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Definition: CallEvent.h:205
QualType getType() const
Definition: Expr.h:127
StringRef Name
Definition: USRFinder.cpp:123
BinaryOperator::Opcode getOpcode(const SymExpr *SE)
detail::InMemoryDirectory::const_iterator E
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2263
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:140
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
Decl * getCalleeDecl()
Definition: Expr.cpp:1220
QualType getResultType() const
Returns the result type, adjusted for references.
Definition: CallEvent.cpp:28
ConstraintManager & getConstraintManager()
Definition: ProgramState.h:530
BasicValueFactory & getBasicValueFactory()
Definition: SValBuilder.h:144
QualType getCanonicalType() const
Definition: Type.h:5528
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
#define CASE
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2206
const llvm::APSInt & getMaxValue(const llvm::APSInt &v)
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:897
CanQualType IntTy
Definition: ASTContext.h:971
#define INVALIDATION_APPROACH(x)
#define END_ARGUMENT_CONDITION
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:683
SVal getReturnValue() const
Returns the return value of the call.
Definition: CallEvent.cpp:240
const LocationContext * getLocationContext() const