Coverage Report

Created: 2020-09-19 12:23

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
Line
Count
Source (jump to first uncovered line)
1
//= CStringChecker.cpp - Checks calls to C string functions --------*- 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 CStringChecker, which is an assortment of checks on calls
10
// to functions in <string.h>.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "InterCheckerAPI.h"
15
#include "clang/Basic/CharInfo.h"
16
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
17
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
18
#include "clang/StaticAnalyzer/Core/Checker.h"
19
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
20
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
21
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
22
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
23
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
24
#include "llvm/ADT/STLExtras.h"
25
#include "llvm/ADT/SmallString.h"
26
#include "llvm/ADT/StringExtras.h"
27
#include "llvm/Support/raw_ostream.h"
28
29
using namespace clang;
30
using namespace ento;
31
32
namespace {
33
struct AnyArgExpr {
34
  // FIXME: Remove constructor in C++17 to turn it into an aggregate.
35
  AnyArgExpr(const Expr *Expression, unsigned ArgumentIndex)
36
4.71k
      : Expression{Expression}, ArgumentIndex{ArgumentIndex} {}
37
  const Expr *Expression;
38
  unsigned ArgumentIndex;
39
};
40
41
struct SourceArgExpr : AnyArgExpr {
42
  using AnyArgExpr::AnyArgExpr; // FIXME: Remove using in C++17.
43
};
44
45
struct DestinationArgExpr : AnyArgExpr {
46
  using AnyArgExpr::AnyArgExpr; // FIXME: Same.
47
};
48
49
struct SizeArgExpr : AnyArgExpr {
50
  using AnyArgExpr::AnyArgExpr; // FIXME: Same.
51
};
52
53
using ErrorMessage = SmallString<128>;
54
enum class AccessKind { write, read };
55
56
static ErrorMessage createOutOfBoundErrorMsg(StringRef FunctionDescription,
57
125
                                             AccessKind Access) {
58
125
  ErrorMessage Message;
59
125
  llvm::raw_svector_ostream Os(Message);
60
125
61
  // Function classification like: Memory copy function
62
125
  Os << toUppercase(FunctionDescription.front())
63
125
     << &FunctionDescription.data()[1];
64
125
65
125
  if (Access == AccessKind::write) {
66
93
    Os << " overflows the destination buffer";
67
32
  } else { // read access
68
32
    Os << " accesses out-of-bound array element";
69
32
  }
70
125
71
125
  return Message;
72
125
}
73
74
enum class ConcatFnKind { none = 0, strcat = 1, strlcat = 2 };
75
class CStringChecker : public Checker< eval::Call,
76
                                         check::PreStmt<DeclStmt>,
77
                                         check::LiveSymbols,
78
                                         check::DeadSymbols,
79
                                         check::RegionChanges
80
                                         > {
81
  mutable std::unique_ptr<BugType> BT_Null, BT_Bounds, BT_Overlap,
82
      BT_NotCString, BT_AdditionOverflow;
83
84
  mutable const char *CurrentFunctionDescription;
85
86
public:
87
  /// The filter is used to filter out the diagnostics which are not enabled by
88
  /// the user.
89
  struct CStringChecksFilter {
90
    DefaultBool CheckCStringNullArg;
91
    DefaultBool CheckCStringOutOfBounds;
92
    DefaultBool CheckCStringBufferOverlap;
93
    DefaultBool CheckCStringNotNullTerm;
94
95
    CheckerNameRef CheckNameCStringNullArg;
96
    CheckerNameRef CheckNameCStringOutOfBounds;
97
    CheckerNameRef CheckNameCStringBufferOverlap;
98
    CheckerNameRef CheckNameCStringNotNullTerm;
99
  };
100
101
  CStringChecksFilter Filter;
102
103
617
  static void *getTag() { static int tag; return &tag; }
104
105
  bool evalCall(const CallEvent &Call, CheckerContext &C) const;
106
  void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
107
  void checkLiveSymbols(ProgramStateRef state, SymbolReaper &SR) const;
108
  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
109
110
  ProgramStateRef
111
    checkRegionChanges(ProgramStateRef state,
112
                       const InvalidatedSymbols *,
113
                       ArrayRef<const MemRegion *> ExplicitRegions,
114
                       ArrayRef<const MemRegion *> Regions,
115
                       const LocationContext *LCtx,
116
                       const CallEvent *Call) const;
117
118
  typedef void (CStringChecker::*FnCheck)(CheckerContext &,
119
                                          const CallExpr *) const;
120
  CallDescriptionMap<FnCheck> Callbacks = {
121
      {{CDF_MaybeBuiltin, "memcpy", 3}, &CStringChecker::evalMemcpy},
122
      {{CDF_MaybeBuiltin, "mempcpy", 3}, &CStringChecker::evalMempcpy},
123
      {{CDF_MaybeBuiltin, "memcmp", 3}, &CStringChecker::evalMemcmp},
124
      {{CDF_MaybeBuiltin, "memmove", 3}, &CStringChecker::evalMemmove},
125
      {{CDF_MaybeBuiltin, "memset", 3}, &CStringChecker::evalMemset},
126
      {{CDF_MaybeBuiltin, "explicit_memset", 3}, &CStringChecker::evalMemset},
127
      {{CDF_MaybeBuiltin, "strcpy", 2}, &CStringChecker::evalStrcpy},
128
      {{CDF_MaybeBuiltin, "strncpy", 3}, &CStringChecker::evalStrncpy},
129
      {{CDF_MaybeBuiltin, "stpcpy", 2}, &CStringChecker::evalStpcpy},
130
      {{CDF_MaybeBuiltin, "strlcpy", 3}, &CStringChecker::evalStrlcpy},
131
      {{CDF_MaybeBuiltin, "strcat", 2}, &CStringChecker::evalStrcat},
132
      {{CDF_MaybeBuiltin, "strncat", 3}, &CStringChecker::evalStrncat},
133
      {{CDF_MaybeBuiltin, "strlcat", 3}, &CStringChecker::evalStrlcat},
134
      {{CDF_MaybeBuiltin, "strlen", 1}, &CStringChecker::evalstrLength},
135
      {{CDF_MaybeBuiltin, "strnlen", 2}, &CStringChecker::evalstrnLength},
136
      {{CDF_MaybeBuiltin, "strcmp", 2}, &CStringChecker::evalStrcmp},
137
      {{CDF_MaybeBuiltin, "strncmp", 3}, &CStringChecker::evalStrncmp},
138
      {{CDF_MaybeBuiltin, "strcasecmp", 2}, &CStringChecker::evalStrcasecmp},
139
      {{CDF_MaybeBuiltin, "strncasecmp", 3}, &CStringChecker::evalStrncasecmp},
140
      {{CDF_MaybeBuiltin, "strsep", 2}, &CStringChecker::evalStrsep},
141
      {{CDF_MaybeBuiltin, "bcopy", 3}, &CStringChecker::evalBcopy},
142
      {{CDF_MaybeBuiltin, "bcmp", 3}, &CStringChecker::evalMemcmp},
143
      {{CDF_MaybeBuiltin, "bzero", 2}, &CStringChecker::evalBzero},
144
      {{CDF_MaybeBuiltin, "explicit_bzero", 2}, &CStringChecker::evalBzero},
145
  };
146
147
  // These require a bit of special handling.
148
  CallDescription StdCopy{{"std", "copy"}, 3},
149
      StdCopyBackward{{"std", "copy_backward"}, 3};
150
151
  FnCheck identifyCall(const CallEvent &Call, CheckerContext &C) const;
152
  void evalMemcpy(CheckerContext &C, const CallExpr *CE) const;
153
  void evalMempcpy(CheckerContext &C, const CallExpr *CE) const;
154
  void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
155
  void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
156
  void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
157
                      ProgramStateRef state, SizeArgExpr Size,
158
                      DestinationArgExpr Dest, SourceArgExpr Source,
159
                      bool Restricted, bool IsMempcpy) const;
160
161
  void evalMemcmp(CheckerContext &C, const CallExpr *CE) const;
162
163
  void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
164
  void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
165
  void evalstrLengthCommon(CheckerContext &C,
166
                           const CallExpr *CE,
167
                           bool IsStrnlen = false) const;
168
169
  void evalStrcpy(CheckerContext &C, const CallExpr *CE) const;
170
  void evalStrncpy(CheckerContext &C, const CallExpr *CE) const;
171
  void evalStpcpy(CheckerContext &C, const CallExpr *CE) const;
172
  void evalStrlcpy(CheckerContext &C, const CallExpr *CE) const;
173
  void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd,
174
                        bool IsBounded, ConcatFnKind appendK,
175
                        bool returnPtr = true) const;
176
177
  void evalStrcat(CheckerContext &C, const CallExpr *CE) const;
178
  void evalStrncat(CheckerContext &C, const CallExpr *CE) const;
179
  void evalStrlcat(CheckerContext &C, const CallExpr *CE) const;
180
181
  void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
182
  void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
183
  void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
184
  void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const;
185
  void evalStrcmpCommon(CheckerContext &C,
186
                        const CallExpr *CE,
187
                        bool IsBounded = false,
188
                        bool IgnoreCase = false) const;
189
190
  void evalStrsep(CheckerContext &C, const CallExpr *CE) const;
191
192
  void evalStdCopy(CheckerContext &C, const CallExpr *CE) const;
193
  void evalStdCopyBackward(CheckerContext &C, const CallExpr *CE) const;
194
  void evalStdCopyCommon(CheckerContext &C, const CallExpr *CE) const;
195
  void evalMemset(CheckerContext &C, const CallExpr *CE) const;
196
  void evalBzero(CheckerContext &C, const CallExpr *CE) const;
197
198
  // Utility methods
199
  std::pair<ProgramStateRef , ProgramStateRef >
200
  static assumeZero(CheckerContext &C,
201
                    ProgramStateRef state, SVal V, QualType Ty);
202
203
  static ProgramStateRef setCStringLength(ProgramStateRef state,
204
                                              const MemRegion *MR,
205
                                              SVal strLength);
206
  static SVal getCStringLengthForRegion(CheckerContext &C,
207
                                        ProgramStateRef &state,
208
                                        const Expr *Ex,
209
                                        const MemRegion *MR,
210
                                        bool hypothetical);
211
  SVal getCStringLength(CheckerContext &C,
212
                        ProgramStateRef &state,
213
                        const Expr *Ex,
214
                        SVal Buf,
215
                        bool hypothetical = false) const;
216
217
  const StringLiteral *getCStringLiteral(CheckerContext &C,
218
                                         ProgramStateRef &state,
219
                                         const Expr *expr,
220
                                         SVal val) const;
221
222
  static ProgramStateRef InvalidateBuffer(CheckerContext &C,
223
                                          ProgramStateRef state,
224
                                          const Expr *Ex, SVal V,
225
                                          bool IsSourceBuffer,
226
                                          const Expr *Size);
227
228
  static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
229
                              const MemRegion *MR);
230
231
  static bool memsetAux(const Expr *DstBuffer, SVal CharE,
232
                        const Expr *Size, CheckerContext &C,
233
                        ProgramStateRef &State);
234
235
  // Re-usable checks
236
  ProgramStateRef checkNonNull(CheckerContext &C, ProgramStateRef State,
237
                               AnyArgExpr Arg, SVal l) const;
238
  ProgramStateRef CheckLocation(CheckerContext &C, ProgramStateRef state,
239
                                AnyArgExpr Buffer, SVal Element,
240
                                AccessKind Access) const;
241
  ProgramStateRef CheckBufferAccess(CheckerContext &C, ProgramStateRef State,
242
                                    AnyArgExpr Buffer, SizeArgExpr Size,
243
                                    AccessKind Access) const;
244
  ProgramStateRef CheckOverlap(CheckerContext &C, ProgramStateRef state,
245
                               SizeArgExpr Size, AnyArgExpr First,
246
                               AnyArgExpr Second) const;
247
  void emitOverlapBug(CheckerContext &C,
248
                      ProgramStateRef state,
249
                      const Stmt *First,
250
                      const Stmt *Second) const;
251
252
  void emitNullArgBug(CheckerContext &C, ProgramStateRef State, const Stmt *S,
253
                      StringRef WarningMsg) const;
254
  void emitOutOfBoundsBug(CheckerContext &C, ProgramStateRef State,
255
                          const Stmt *S, StringRef WarningMsg) const;
256
  void emitNotCStringBug(CheckerContext &C, ProgramStateRef State,
257
                         const Stmt *S, StringRef WarningMsg) const;
258
  void emitAdditionOverflowBug(CheckerContext &C, ProgramStateRef State) const;
259
260
  ProgramStateRef checkAdditionOverflow(CheckerContext &C,
261
                                            ProgramStateRef state,
262
                                            NonLoc left,
263
                                            NonLoc right) const;
264
265
  // Return true if the destination buffer of the copy function may be in bound.
266
  // Expects SVal of Size to be positive and unsigned.
267
  // Expects SVal of FirstBuf to be a FieldRegion.
268
  static bool IsFirstBufInBound(CheckerContext &C,
269
                                ProgramStateRef state,
270
                                const Expr *FirstBuf,
271
                                const Expr *Size);
272
};
273
274
} //end anonymous namespace
275
276
REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal)
277
278
//===----------------------------------------------------------------------===//
279
// Individual checks and utility methods.
280
//===----------------------------------------------------------------------===//
281
282
std::pair<ProgramStateRef , ProgramStateRef >
283
CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V,
284
4.58k
                           QualType Ty) {
285
4.58k
  Optional<DefinedSVal> val = V.getAs<DefinedSVal>();
286
4.58k
  if (!val)
287
11
    return std::pair<ProgramStateRef , ProgramStateRef >(state, state);
288
4.57k
289
4.57k
  SValBuilder &svalBuilder = C.getSValBuilder();
290
4.57k
  DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
291
4.57k
  return state->assume(svalBuilder.evalEQ(state, *val, zero));
292
4.57k
}
293
294
ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
295
                                             ProgramStateRef State,
296
3.67k
                                             AnyArgExpr Arg, SVal l) const {
297
  // If a previous check has failed, propagate the failure.
298
3.67k
  if (!State)
299
0
    return nullptr;
300
3.67k
301
3.67k
  ProgramStateRef stateNull, stateNonNull;
302
3.67k
  std::tie(stateNull, stateNonNull) =
303
3.67k
      assumeZero(C, State, l, Arg.Expression->getType());
304
3.67k
305
3.67k
  if (stateNull && 
!stateNonNull572
) {
306
169
    if (Filter.CheckCStringNullArg) {
307
169
      SmallString<80> buf;
308
169
      llvm::raw_svector_ostream OS(buf);
309
169
      assert(CurrentFunctionDescription);
310
169
      OS << "Null pointer passed as " << (Arg.ArgumentIndex + 1)
311
169
         << llvm::getOrdinalSuffix(Arg.ArgumentIndex + 1) << " argument to "
312
169
         << CurrentFunctionDescription;
313
169
314
169
      emitNullArgBug(C, stateNull, Arg.Expression, OS.str());
315
169
    }
316
169
    return nullptr;
317
169
  }
318
3.51k
319
  // From here on, assume that the value is non-null.
320
3.51k
  assert(stateNonNull);
321
3.51k
  return stateNonNull;
322
3.51k
}
323
324
// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
325
ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
326
                                              ProgramStateRef state,
327
                                              AnyArgExpr Buffer, SVal Element,
328
778
                                              AccessKind Access) const {
329
778
330
  // If a previous check has failed, propagate the failure.
331
778
  if (!state)
332
0
    return nullptr;
333
778
334
  // Check for out of bound array element access.
335
778
  const MemRegion *R = Element.getAsRegion();
336
778
  if (!R)
337
0
    return state;
338
778
339
778
  const auto *ER = dyn_cast<ElementRegion>(R);
340
778
  if (!ER)
341
0
    return state;
342
778
343
778
  if (ER->getValueType() != C.getASTContext().CharTy)
344
1
    return state;
345
777
346
  // Get the size of the array.
347
777
  const auto *superReg = cast<SubRegion>(ER->getSuperRegion());
348
777
  DefinedOrUnknownSVal Size =
349
777
      getDynamicSize(state, superReg, C.getSValBuilder());
350
777
351
  // Get the index of the accessed element.
352
777
  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
353
777
354
777
  ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
355
777
  ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
356
777
  if (StOutBound && 
!StInBound268
) {
357
    // These checks are either enabled by the CString out-of-bounds checker
358
    // explicitly or implicitly by the Malloc checker.
359
    // In the latter case we only do modeling but do not emit warning.
360
150
    if (!Filter.CheckCStringOutOfBounds)
361
25
      return nullptr;
362
125
363
    // Emit a bug report.
364
125
    ErrorMessage Message =
365
125
        createOutOfBoundErrorMsg(CurrentFunctionDescription, Access);
366
125
    emitOutOfBoundsBug(C, StOutBound, Buffer.Expression, Message);
367
125
    return nullptr;
368
125
  }
369
627
370
  // Array bound check succeeded.  From this point forward the array bound
371
  // should always succeed.
372
627
  return StInBound;
373
627
}
374
375
ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
376
                                                  ProgramStateRef State,
377
                                                  AnyArgExpr Buffer,
378
                                                  SizeArgExpr Size,
379
668
                                                  AccessKind Access) const {
380
  // If a previous check has failed, propagate the failure.
381
668
  if (!State)
382
36
    return nullptr;
383
632
384
632
  SValBuilder &svalBuilder = C.getSValBuilder();
385
632
  ASTContext &Ctx = svalBuilder.getContext();
386
632
387
632
  QualType SizeTy = Size.Expression->getType();
388
632
  QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
389
632
390
  // Check that the first buffer is non-null.
391
632
  SVal BufVal = C.getSVal(Buffer.Expression);
392
632
  State = checkNonNull(C, State, Buffer, BufVal);
393
632
  if (!State)
394
4
    return nullptr;
395
628
396
  // If out-of-bounds checking is turned off, skip the rest.
397
628
  if (!Filter.CheckCStringOutOfBounds)
398
156
    return State;
399
472
400
  // Get the access length and make sure it is known.
401
  // FIXME: This assumes the caller has already checked that the access length
402
  // is positive. And that it's unsigned.
403
472
  SVal LengthVal = C.getSVal(Size.Expression);
404
472
  Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
405
472
  if (!Length)
406
8
    return State;
407
464
408
  // Compute the offset of the last element to be accessed: size-1.
409
464
  NonLoc One = svalBuilder.makeIntVal(1, SizeTy).castAs<NonLoc>();
410
464
  SVal Offset = svalBuilder.evalBinOpNN(State, BO_Sub, *Length, One, SizeTy);
411
464
  if (Offset.isUnknown())
412
4
    return nullptr;
413
460
  NonLoc LastOffset = Offset.castAs<NonLoc>();
414
460
415
  // Check that the first buffer is sufficiently long.
416
460
  SVal BufStart =
417
460
      svalBuilder.evalCast(BufVal, PtrTy, Buffer.Expression->getType());
418
460
  if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
419
456
420
456
    SVal BufEnd =
421
456
        svalBuilder.evalBinOpLN(State, BO_Add, *BufLoc, LastOffset, PtrTy);
422
456
423
456
    State = CheckLocation(C, State, Buffer, BufEnd, Access);
424
456
425
    // If the buffer isn't large enough, abort.
426
456
    if (!State)
427
62
      return nullptr;
428
398
  }
429
398
430
  // Large enough or not, return this state!
431
398
  return State;
432
398
}
433
434
ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
435
                                             ProgramStateRef state,
436
                                             SizeArgExpr Size, AnyArgExpr First,
437
524
                                             AnyArgExpr Second) const {
438
524
  if (!Filter.CheckCStringBufferOverlap)
439
173
    return state;
440
351
441
  // Do a simple check for overlap: if the two arguments are from the same
442
  // buffer, see if the end of the first is greater than the start of the second
443
  // or vice versa.
444
351
445
  // If a previous check has failed, propagate the failure.
446
351
  if (!state)
447
36
    return nullptr;
448
315
449
315
  ProgramStateRef stateTrue, stateFalse;
450
315
451
  // Get the buffer values and make sure they're known locations.
452
315
  const LocationContext *LCtx = C.getLocationContext();
453
315
  SVal firstVal = state->getSVal(First.Expression, LCtx);
454
315
  SVal secondVal = state->getSVal(Second.Expression, LCtx);
455
315
456
315
  Optional<Loc> firstLoc = firstVal.getAs<Loc>();
457
315
  if (!firstLoc)
458
0
    return state;
459
315
460
315
  Optional<Loc> secondLoc = secondVal.getAs<Loc>();
461
315
  if (!secondLoc)
462
1
    return state;
463
314
464
  // Are the two values the same?
465
314
  SValBuilder &svalBuilder = C.getSValBuilder();
466
314
  std::tie(stateTrue, stateFalse) =
467
314
      state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
468
314
469
314
  if (stateTrue && 
!stateFalse49
) {
470
    // If the values are known to be equal, that's automatically an overlap.
471
8
    emitOverlapBug(C, stateTrue, First.Expression, Second.Expression);
472
8
    return nullptr;
473
8
  }
474
306
475
  // assume the two expressions are not equal.
476
306
  assert(stateFalse);
477
306
  state = stateFalse;
478
306
479
  // Which value comes first?
480
306
  QualType cmpTy = svalBuilder.getConditionType();
481
306
  SVal reverse =
482
306
      svalBuilder.evalBinOpLL(state, BO_GT, *firstLoc, *secondLoc, cmpTy);
483
306
  Optional<DefinedOrUnknownSVal> reverseTest =
484
306
      reverse.getAs<DefinedOrUnknownSVal>();
485
306
  if (!reverseTest)
486
0
    return state;
487
306
488
306
  std::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
489
306
  if (stateTrue) {
490
289
    if (stateFalse) {
491
      // If we don't know which one comes first, we can't perform this test.
492
273
      return state;
493
16
    } else {
494
      // Switch the values so that firstVal is before secondVal.
495
16
      std::swap(firstLoc, secondLoc);
496
16
497
      // Switch the Exprs as well, so that they still correspond.
498
16
      std::swap(First, Second);
499
16
    }
500
289
  }
501
306
502
  // Get the length, and make sure it too is known.
503
33
  SVal LengthVal = state->getSVal(Size.Expression, LCtx);
504
33
  Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
505
33
  if (!Length)
506
0
    return state;
507
33
508
  // Convert the first buffer's start address to char*.
509
  // Bail out if the cast fails.
510
33
  ASTContext &Ctx = svalBuilder.getContext();
511
33
  QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
512
33
  SVal FirstStart =
513
33
      svalBuilder.evalCast(*firstLoc, CharPtrTy, First.Expression->getType());
514
33
  Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>();
515
33
  if (!FirstStartLoc)
516
0
    return state;
517
33
518
  // Compute the end of the first buffer. Bail out if THAT fails.
519
33
  SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add, *FirstStartLoc,
520
33
                                          *Length, CharPtrTy);
521
33
  Optional<Loc> FirstEndLoc = FirstEnd.getAs<Loc>();
522
33
  if (!FirstEndLoc)
523
0
    return state;
524
33
525
  // Is the end of the first buffer past the start of the second buffer?
526
33
  SVal Overlap =
527
33
      svalBuilder.evalBinOpLL(state, BO_GT, *FirstEndLoc, *secondLoc, cmpTy);
528
33
  Optional<DefinedOrUnknownSVal> OverlapTest =
529
33
      Overlap.getAs<DefinedOrUnknownSVal>();
530
33
  if (!OverlapTest)
531
0
    return state;
532
33
533
33
  std::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
534
33
535
33
  if (stateTrue && 
!stateFalse17
) {
536
    // Overlap!
537
17
    emitOverlapBug(C, stateTrue, First.Expression, Second.Expression);
538
17
    return nullptr;
539
17
  }
540
16
541
  // assume the two expressions don't overlap.
542
16
  assert(stateFalse);
543
16
  return stateFalse;
544
16
}
545
546
void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state,
547
25
                                  const Stmt *First, const Stmt *Second) const {
548
25
  ExplodedNode *N = C.generateErrorNode(state);
549
25
  if (!N)
550
0
    return;
551
25
552
25
  if (!BT_Overlap)
553
5
    BT_Overlap.reset(new BugType(Filter.CheckNameCStringBufferOverlap,
554
5
                                 categories::UnixAPI, "Improper arguments"));
555
25
556
  // Generate a report for this bug.
557
25
  auto report = std::make_unique<PathSensitiveBugReport>(
558
25
      *BT_Overlap, "Arguments must not be overlapping buffers", N);
559
25
  report->addRange(First->getSourceRange());
560
25
  report->addRange(Second->getSourceRange());
561
25
562
25
  C.emitReport(std::move(report));
563
25
}
564
565
void CStringChecker::emitNullArgBug(CheckerContext &C, ProgramStateRef State,
566
169
                                    const Stmt *S, StringRef WarningMsg) const {
567
169
  if (ExplodedNode *N = C.generateErrorNode(State)) {
568
169
    if (!BT_Null)
569
14
      BT_Null.reset(new BuiltinBug(
570
14
          Filter.CheckNameCStringNullArg, categories::UnixAPI,
571
14
          "Null pointer argument in call to byte string function"));
572
169
573
169
    BuiltinBug *BT = static_cast<BuiltinBug *>(BT_Null.get());
574
169
    auto Report = std::make_unique<PathSensitiveBugReport>(*BT, WarningMsg, N);
575
169
    Report->addRange(S->getSourceRange());
576
169
    if (const auto *Ex = dyn_cast<Expr>(S))
577
169
      bugreporter::trackExpressionValue(N, Ex, *Report);
578
169
    C.emitReport(std::move(Report));
579
169
  }
580
169
}
581
582
void CStringChecker::emitOutOfBoundsBug(CheckerContext &C,
583
                                        ProgramStateRef State, const Stmt *S,
584
125
                                        StringRef WarningMsg) const {
585
125
  if (ExplodedNode *N = C.generateErrorNode(State)) {
586
125
    if (!BT_Bounds)
587
10
      BT_Bounds.reset(new BuiltinBug(
588
10
          Filter.CheckCStringOutOfBounds ? Filter.CheckNameCStringOutOfBounds
589
0
                                         : Filter.CheckNameCStringNullArg,
590
10
          "Out-of-bound array access",
591
10
          "Byte string function accesses out-of-bound array element"));
592
125
593
125
    BuiltinBug *BT = static_cast<BuiltinBug *>(BT_Bounds.get());
594
125
595
    // FIXME: It would be nice to eventually make this diagnostic more clear,
596
    // e.g., by referencing the original declaration or by saying *why* this
597
    // reference is outside the range.
598
125
    auto Report = std::make_unique<PathSensitiveBugReport>(*BT, WarningMsg, N);
599
125
    Report->addRange(S->getSourceRange());
600
125
    C.emitReport(std::move(Report));
601
125
  }
602
125
}
603
604
void CStringChecker::emitNotCStringBug(CheckerContext &C, ProgramStateRef State,
605
                                       const Stmt *S,
606
46
                                       StringRef WarningMsg) const {
607
46
  if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) {
608
46
    if (!BT_NotCString)
609
6
      BT_NotCString.reset(new BuiltinBug(
610
6
          Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
611
6
          "Argument is not a null-terminated string."));
612
46
613
46
    auto Report =
614
46
        std::make_unique<PathSensitiveBugReport>(*BT_NotCString, WarningMsg, N);
615
46
616
46
    Report->addRange(S->getSourceRange());
617
46
    C.emitReport(std::move(Report));
618
46
  }
619
46
}
620
621
void CStringChecker::emitAdditionOverflowBug(CheckerContext &C,
622
0
                                             ProgramStateRef State) const {
623
0
  if (ExplodedNode *N = C.generateErrorNode(State)) {
624
0
    if (!BT_NotCString)
625
0
      BT_NotCString.reset(
626
0
          new BuiltinBug(Filter.CheckNameCStringOutOfBounds, "API",
627
0
                         "Sum of expressions causes overflow."));
628
0
629
    // This isn't a great error message, but this should never occur in real
630
    // code anyway -- you'd have to create a buffer longer than a size_t can
631
    // represent, which is sort of a contradiction.
632
0
    const char *WarningMsg =
633
0
        "This expression will create a string whose length is too big to "
634
0
        "be represented as a size_t";
635
0
636
0
    auto Report =
637
0
        std::make_unique<PathSensitiveBugReport>(*BT_NotCString, WarningMsg, N);
638
0
    C.emitReport(std::move(Report));
639
0
  }
640
0
}
641
642
ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
643
                                                     ProgramStateRef state,
644
                                                     NonLoc left,
645
116
                                                     NonLoc right) const {
646
  // If out-of-bounds checking is turned off, skip the rest.
647
116
  if (!Filter.CheckCStringOutOfBounds)
648
39
    return state;
649
77
650
  // If a previous check has failed, propagate the failure.
651
77
  if (!state)
652
0
    return nullptr;
653
77
654
77
  SValBuilder &svalBuilder = C.getSValBuilder();
655
77
  BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
656
77
657
77
  QualType sizeTy = svalBuilder.getContext().getSizeType();
658
77
  const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
659
77
  NonLoc maxVal = svalBuilder.makeIntVal(maxValInt);
660
77
661
77
  SVal maxMinusRight;
662
77
  if (right.getAs<nonloc::ConcreteInt>()) {
663
65
    maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right,
664
65
                                                 sizeTy);
665
12
  } else {
666
    // Try switching the operands. (The order of these two assignments is
667
    // important!)
668
12
    maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left,
669
12
                                            sizeTy);
670
12
    left = right;
671
12
  }
672
77
673
77
  if (Optional<NonLoc> maxMinusRightNL = maxMinusRight.getAs<NonLoc>()) {
674
77
    QualType cmpTy = svalBuilder.getConditionType();
675
    // If left > max - right, we have an overflow.
676
77
    SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
677
77
                                                *maxMinusRightNL, cmpTy);
678
77
679
77
    ProgramStateRef stateOverflow, stateOkay;
680
77
    std::tie(stateOverflow, stateOkay) =
681
77
      state->assume(willOverflow.castAs<DefinedOrUnknownSVal>());
682
77
683
77
    if (stateOverflow && 
!stateOkay0
) {
684
      // We have an overflow. Emit a bug report.
685
0
      emitAdditionOverflowBug(C, stateOverflow);
686
0
      return nullptr;
687
0
    }
688
77
689
    // From now on, assume an overflow didn't occur.
690
77
    assert(stateOkay);
691
77
    state = stateOkay;
692
77
  }
693
77
694
77
  return state;
695
77
}
696
697
ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state,
698
                                                const MemRegion *MR,
699
385
                                                SVal strLength) {
700
385
  assert(!strLength.isUndef() && "Attempt to set an undefined string length");
701
385
702
385
  MR = MR->StripCasts();
703
385
704
385
  switch (MR->getKind()) {
705
0
  case MemRegion::StringRegionKind:
706
    // FIXME: This can happen if we strcpy() into a string region. This is
707
    // undefined [C99 6.4.5p6], but we should still warn about it.
708
0
    return state;
709
0
710
381
  case MemRegion::SymbolicRegionKind:
711
381
  case MemRegion::AllocaRegionKind:
712
381
  case MemRegion::NonParamVarRegionKind:
713
381
  case MemRegion::ParamVarRegionKind:
714
381
  case MemRegion::FieldRegionKind:
715
381
  case MemRegion::ObjCIvarRegionKind:
716
    // These are the types we can currently track string lengths for.
717
381
    break;
718
381
719
4
  case MemRegion::ElementRegionKind:
720
    // FIXME: Handle element regions by upper-bounding the parent region's
721
    // string length.
722
4
    return state;
723
381
724
0
  default:
725
    // Other regions (mostly non-data) can't have a reliable C string length.
726
    // For now, just ignore the change.
727
    // FIXME: These are rare but not impossible. We should output some kind of
728
    // warning for things like strcpy((char[]){'a', 0}, "b");
729
0
    return state;
730
381
  }
731
381
732
381
  if (strLength.isUnknown())
733
51
    return state->remove<CStringLength>(MR);
734
330
735
330
  return state->set<CStringLength>(MR, strLength);
736
330
}
737
738
SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
739
                                               ProgramStateRef &state,
740
                                               const Expr *Ex,
741
                                               const MemRegion *MR,
742
1.22k
                                               bool hypothetical) {
743
1.22k
  if (!hypothetical) {
744
    // If there's a recorded length, go ahead and return it.
745
1.17k
    const SVal *Recorded = state->get<CStringLength>(MR);
746
1.17k
    if (Recorded)
747
661
      return *Recorded;
748
568
  }
749
568
750
  // Otherwise, get a new symbol and update the state.
751
568
  SValBuilder &svalBuilder = C.getSValBuilder();
752
568
  QualType sizeTy = svalBuilder.getContext().getSizeType();
753
568
  SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
754
568
                                                    MR, Ex, sizeTy,
755
568
                                                    C.getLocationContext(),
756
568
                                                    C.blockCount());
757
568
758
568
  if (!hypothetical) {
759
516
    if (Optional<NonLoc> strLn = strLength.getAs<NonLoc>()) {
760
      // In case of unbounded calls strlen etc bound the range to SIZE_MAX/4
761
516
      BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
762
516
      const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
763
516
      llvm::APSInt fourInt = APSIntType(maxValInt).getValue(4);
764
516
      const llvm::APSInt *maxLengthInt = BVF.evalAPSInt(BO_Div, maxValInt,
765
516
                                                        fourInt);
766
516
      NonLoc maxLength = svalBuilder.makeIntVal(*maxLengthInt);
767
516
      SVal evalLength = svalBuilder.evalBinOpNN(state, BO_LE, *strLn,
768
516
                                                maxLength, sizeTy);
769
516
      state = state->assume(evalLength.castAs<DefinedOrUnknownSVal>(), true);
770
516
    }
771
516
    state = state->set<CStringLength>(MR, strLength);
772
516
  }
773
568
774
568
  return strLength;
775
568
}
776
777
SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
778
                                      const Expr *Ex, SVal Buf,
779
2.40k
                                      bool hypothetical) const {
780
2.40k
  const MemRegion *MR = Buf.getAsRegion();
781
2.40k
  if (!MR) {
782
    // If we can't get a region, see if it's something we /know/ isn't a
783
    // C string. In the context of locations, the only time we can issue such
784
    // a warning is for labels.
785
16
    if (Optional<loc::GotoLabel> Label = Buf.getAs<loc::GotoLabel>()) {
786
10
      if (Filter.CheckCStringNotNullTerm) {
787
10
        SmallString<120> buf;
788
10
        llvm::raw_svector_ostream os(buf);
789
10
        assert(CurrentFunctionDescription);
790
10
        os << "Argument to " << CurrentFunctionDescription
791
10
           << " is the address of the label '" << Label->getLabel()->getName()
792
10
           << "', which is not a null-terminated string";
793
10
794
10
        emitNotCStringBug(C, state, Ex, os.str());
795
10
      }
796
10
      return UndefinedVal();
797
10
    }
798
6
799
    // If it's not a region and not a label, give up.
800
6
    return UnknownVal();
801
6
  }
802
2.38k
803
  // If we have a region, strip casts from it and see if we can figure out
804
  // its length. For anything we can't figure out, just return UnknownVal.
805
2.38k
  MR = MR->StripCasts();
806
2.38k
807
2.38k
  switch (MR->getKind()) {
808
1.08k
  case MemRegion::StringRegionKind: {
809
    // Modifying the contents of string regions is undefined [C99 6.4.5p6],
810
    // so we can assume that the byte length is the correct C string length.
811
1.08k
    SValBuilder &svalBuilder = C.getSValBuilder();
812
1.08k
    QualType sizeTy = svalBuilder.getContext().getSizeType();
813
1.08k
    const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
814
1.08k
    return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
815
0
  }
816
1.22k
  case MemRegion::SymbolicRegionKind:
817
1.22k
  case MemRegion::AllocaRegionKind:
818
1.22k
  case MemRegion::NonParamVarRegionKind:
819
1.22k
  case MemRegion::ParamVarRegionKind:
820
1.22k
  case MemRegion::FieldRegionKind:
821
1.22k
  case MemRegion::ObjCIvarRegionKind:
822
1.22k
    return getCStringLengthForRegion(C, state, Ex, MR, hypothetical);
823
5
  case MemRegion::CompoundLiteralRegionKind:
824
    // FIXME: Can we track this? Is it necessary?
825
5
    return UnknownVal();
826
31
  case MemRegion::ElementRegionKind:
827
    // FIXME: How can we handle this? It's not good enough to subtract the
828
    // offset from the base string length; consider "123\x00567" and &a[5].
829
31
    return UnknownVal();
830
36
  default:
831
    // Other regions (mostly non-data) can't have a reliable C string length.
832
    // In this case, an error is emitted and UndefinedVal is returned.
833
    // The caller should always be prepared to handle this case.
834
36
    if (Filter.CheckCStringNotNullTerm) {
835
36
      SmallString<120> buf;
836
36
      llvm::raw_svector_ostream os(buf);
837
36
838
36
      assert(CurrentFunctionDescription);
839
36
      os << "Argument to " << CurrentFunctionDescription << " is ";
840
36
841
36
      if (SummarizeRegion(os, C.getASTContext(), MR))
842
36
        os << ", which is not a null-terminated string";
843
0
      else
844
0
        os << "not a null-terminated string";
845
36
846
36
      emitNotCStringBug(C, state, Ex, os.str());
847
36
    }
848
36
    return UndefinedVal();
849
2.38k
  }
850
2.38k
}
851
852
const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
853
752
  ProgramStateRef &state, const Expr *expr, SVal val) const {
854
752
855
  // Get the memory region pointed to by the val.
856
752
  const MemRegion *bufRegion = val.getAsRegion();
857
752
  if (!bufRegion)
858
5
    return nullptr;
859
747
860
  // Strip casts off the memory region.
861
747
  bufRegion = bufRegion->StripCasts();
862
747
863
  // Cast the memory region to a string region.
864
747
  const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
865
747
  if (!strRegion)
866
2
    return nullptr;
867
745
868
  // Return the actual string in the string region.
869
745
  return strRegion->getStringLiteral();
870
745
}
871
872
bool CStringChecker::IsFirstBufInBound(CheckerContext &C,
873
                                       ProgramStateRef state,
874
                                       const Expr *FirstBuf,
875
42
                                       const Expr *Size) {
876
  // If we do not know that the buffer is long enough we return 'true'.
877
  // Otherwise the parent region of this field region would also get
878
  // invalidated, which would lead to warnings based on an unknown state.
879
42
880
  // Originally copied from CheckBufferAccess and CheckLocation.
881
42
  SValBuilder &svalBuilder = C.getSValBuilder();
882
42
  ASTContext &Ctx = svalBuilder.getContext();
883
42
  const LocationContext *LCtx = C.getLocationContext();
884
42
885
42
  QualType sizeTy = Size->getType();
886
42
  QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
887
42
  SVal BufVal = state->getSVal(FirstBuf, LCtx);
888
42
889
42
  SVal LengthVal = state->getSVal(Size, LCtx);
890
42
  Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
891
42
  if (!Length)
892
1
    return true; // cf top comment.
893
41
894
  // Compute the offset of the last element to be accessed: size-1.
895
41
  NonLoc One = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
896
41
  SVal Offset = svalBuilder.evalBinOpNN(state, BO_Sub, *Length, One, sizeTy);
897
41
  if (Offset.isUnknown())
898
0
    return true; // cf top comment
899
41
  NonLoc LastOffset = Offset.castAs<NonLoc>();
900
41
901
  // Check that the first buffer is sufficiently long.
902
41
  SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
903
41
  Optional<Loc> BufLoc = BufStart.getAs<Loc>();
904
41
  if (!BufLoc)
905
1
    return true; // cf top comment.
906
40
907
40
  SVal BufEnd =
908
40
      svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, LastOffset, PtrTy);
909
40
910
  // Check for out of bound array element access.
911
40
  const MemRegion *R = BufEnd.getAsRegion();
912
40
  if (!R)
913
0
    return true; // cf top comment.
914
40
915
40
  const ElementRegion *ER = dyn_cast<ElementRegion>(R);
916
40
  if (!ER)
917
0
    return true; // cf top comment.
918
40
919
  // FIXME: Does this crash when a non-standard definition
920
  // of a library function is encountered?
921
40
  assert(ER->getValueType() == C.getASTContext().CharTy &&
922
40
         "IsFirstBufInBound should only be called with char* ElementRegions");
923
40
924
  // Get the size of the array.
925
40
  const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
926
40
  DefinedOrUnknownSVal SizeDV = getDynamicSize(state, superReg, svalBuilder);
927
40
928
  // Get the index of the accessed element.
929
40
  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
930
40
931
40
  ProgramStateRef StInBound = state->assumeInBound(Idx, SizeDV, true);
932
40
933
40
  return static_cast<bool>(StInBound);
934
40
}
935
936
ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
937
                                                 ProgramStateRef state,
938
                                                 const Expr *E, SVal V,
939
                                                 bool IsSourceBuffer,
940
859
                                                 const Expr *Size) {
941
859
  Optional<Loc> L = V.getAs<Loc>();
942
859
  if (!L)
943
0
    return state;
944
859
945
  // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
946
  // some assumptions about the value that CFRefCount can't. Even so, it should
947
  // probably be refactored.
948
859
  if (Optional<loc::MemRegionVal> MR = L->getAs<loc::MemRegionVal>()) {
949
853
    const MemRegion *R = MR->getRegion()->StripCasts();
950
853
951
    // Are we dealing with an ElementRegion?  If so, we should be invalidating
952
    // the super-region.
953
853
    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
954
97
      R = ER->getSuperRegion();
955
      // FIXME: What about layers of ElementRegions?
956
97
    }
957
853
958
    // Invalidate this region.
959
853
    const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
960
853
961
853
    bool CausesPointerEscape = false;
962
853
    RegionAndSymbolInvalidationTraits ITraits;
963
    // Invalidate and escape only indirect regions accessible through the source
964
    // buffer.
965
853
    if (IsSourceBuffer) {
966
374
      ITraits.setTrait(R->getBaseRegion(),
967
374
                       RegionAndSymbolInvalidationTraits::TK_PreserveContents);
968
374
      ITraits.setTrait(R, RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
969
374
      CausesPointerEscape = true;
970
479
    } else {
971
479
      const MemRegion::Kind& K = R->getKind();
972
479
      if (K == MemRegion::FieldRegionKind)
973
42
        if (Size && IsFirstBufInBound(C, state, E, Size)) {
974
          // If destination buffer is a field region and access is in bound,
975
          // do not invalidate its super region.
976
35
          ITraits.setTrait(
977
35
              R,
978
35
              RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
979
35
        }
980
479
    }
981
853
982
853
    return state->invalidateRegions(R, E, C.blockCount(), LCtx,
983
853
                                    CausesPointerEscape, nullptr, nullptr,
984
853
                                    &ITraits);
985
853
  }
986
6
987
  // If we have a non-region value by chance, just remove the binding.
988
  // FIXME: is this necessary or correct? This handles the non-Region
989
  //  cases.  Is it ever valid to store to these?
990
6
  return state->killBinding(*L);
991
6
}
992
993
bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
994
36
                                     const MemRegion *MR) {
995
36
  switch (MR->getKind()) {
996
36
  case MemRegion::FunctionCodeRegionKind: {
997
36
    if (const auto *FD = cast<FunctionCodeRegion>(MR)->getDecl())
998
36
      os << "the address of the function '" << *FD << '\'';
999
0
    else
1000
0
      os << "the address of a function";
1001
36
    return true;
1002
0
  }
1003
0
  case MemRegion::BlockCodeRegionKind:
1004
0
    os << "block text";
1005
0
    return true;
1006
0
  case MemRegion::BlockDataRegionKind:
1007
0
    os << "a block";
1008
0
    return true;
1009
0
  case MemRegion::CXXThisRegionKind:
1010
0
  case MemRegion::CXXTempObjectRegionKind:
1011
0
    os << "a C++ temp object of type "
1012
0
       << cast<TypedValueRegion>(MR)->getValueType().getAsString();
1013
0
    return true;
1014
0
  case MemRegion::NonParamVarRegionKind:
1015
0
    os << "a variable of type"
1016
0
       << cast<TypedValueRegion>(MR)->getValueType().getAsString();
1017
0
    return true;
1018
0
  case MemRegion::ParamVarRegionKind:
1019
0
    os << "a parameter of type"
1020
0
       << cast<TypedValueRegion>(MR)->getValueType().getAsString();
1021
0
    return true;
1022
0
  case MemRegion::FieldRegionKind:
1023
0
    os << "a field of type "
1024
0
       << cast<TypedValueRegion>(MR)->getValueType().getAsString();
1025
0
    return true;
1026
0
  case MemRegion::ObjCIvarRegionKind:
1027
0
    os << "an instance variable of type "
1028
0
       << cast<TypedValueRegion>(MR)->getValueType().getAsString();
1029
0
    return true;
1030
0
  default:
1031
0
    return false;
1032
36
  }
1033
36
}
1034
1035
bool CStringChecker::memsetAux(const Expr *DstBuffer, SVal CharVal,
1036
                               const Expr *Size, CheckerContext &C,
1037
172
                               ProgramStateRef &State) {
1038
172
  SVal MemVal = C.getSVal(DstBuffer);
1039
172
  SVal SizeVal = C.getSVal(Size);
1040
172
  const MemRegion *MR = MemVal.getAsRegion();
1041
172
  if (!MR)
1042
0
    return false;
1043
172
1044
  // We're about to model memset by producing a "default binding" in the Store.
1045
  // Our current implementation - RegionStore - doesn't support default bindings
1046
  // that don't cover the whole base region. So we should first get the offset
1047
  // and the base region to figure out whether the offset of buffer is 0.
1048
172
  RegionOffset Offset = MR->getAsOffset();
1049
172
  const MemRegion *BR = Offset.getRegion();
1050
172
1051
172
  Optional<NonLoc> SizeNL = SizeVal.getAs<NonLoc>();
1052
172
  if (!SizeNL)
1053
0
    return false;
1054
172
1055
172
  SValBuilder &svalBuilder = C.getSValBuilder();
1056
172
  ASTContext &Ctx = C.getASTContext();
1057
172
1058
  // void *memset(void *dest, int ch, size_t count);
1059
  // For now we can only handle the case of offset is 0 and concrete char value.
1060
172
  if (Offset.isValid() && !Offset.hasSymbolicOffset() &&
1061
171
      Offset.getOffset() == 0) {
1062
    // Get the base region's size.
1063
145
    DefinedOrUnknownSVal SizeDV = getDynamicSize(State, BR, svalBuilder);
1064
145
1065
145
    ProgramStateRef StateWholeReg, StateNotWholeReg;
1066
145
    std::tie(StateWholeReg, StateNotWholeReg) =
1067
145
        State->assume(svalBuilder.evalEQ(State, SizeDV, *SizeNL));
1068
145
1069
    // With the semantic of 'memset()', we should convert the CharVal to
1070
    // unsigned char.
1071
145
    CharVal = svalBuilder.evalCast(CharVal, Ctx.UnsignedCharTy, Ctx.IntTy);
1072
145
1073
145
    ProgramStateRef StateNullChar, StateNonNullChar;
1074
145
    std::tie(StateNullChar, StateNonNullChar) =
1075
145
        assumeZero(C, State, CharVal, Ctx.UnsignedCharTy);
1076
145
1077
145
    if (StateWholeReg && 
!StateNotWholeReg113
&&
StateNullChar113
&&
1078
91
        !StateNonNullChar) {
1079
      // If the 'memset()' acts on the whole region of destination buffer and
1080
      // the value of the second argument of 'memset()' is zero, bind the second
1081
      // argument's value to the destination buffer with 'default binding'.
1082
      // FIXME: Since there is no perfect way to bind the non-zero character, we
1083
      // can only deal with zero value here. In the future, we need to deal with
1084
      // the binding of non-zero value in the case of whole region.
1085
91
      State = State->bindDefaultZero(svalBuilder.makeLoc(BR),
1086
91
                                     C.getLocationContext());
1087
54
    } else {
1088
      // If the destination buffer's extent is not equal to the value of
1089
      // third argument, just invalidate buffer.
1090
54
      State = InvalidateBuffer(C, State, DstBuffer, MemVal,
1091
54
                               /*IsSourceBuffer*/ false, Size);
1092
54
    }
1093
145
1094
145
    if (StateNullChar && 
!StateNonNullChar116
) {
1095
      // If the value of the second argument of 'memset()' is zero, set the
1096
      // string length of destination buffer to 0 directly.
1097
116
      State = setCStringLength(State, MR,
1098
116
                               svalBuilder.makeZeroVal(Ctx.getSizeType()));
1099
29
    } else if (!StateNullChar && StateNonNullChar) {
1100
29
      SVal NewStrLen = svalBuilder.getMetadataSymbolVal(
1101
29
          CStringChecker::getTag(), MR, DstBuffer, Ctx.getSizeType(),
1102
29
          C.getLocationContext(), C.blockCount());
1103
29
1104
      // If the value of second argument is not zero, then the string length
1105
      // is at least the size argument.
1106
29
      SVal NewStrLenGESize = svalBuilder.evalBinOp(
1107
29
          State, BO_GE, NewStrLen, SizeVal, svalBuilder.getConditionType());
1108
29
1109
29
      State = setCStringLength(
1110
29
          State->assume(NewStrLenGESize.castAs<DefinedOrUnknownSVal>(), true),
1111
29
          MR, NewStrLen);
1112
29
    }
1113
27
  } else {
1114
    // If the offset is not zero and char value is not concrete, we can do
1115
    // nothing but invalidate the buffer.
1116
27
    State = InvalidateBuffer(C, State, DstBuffer, MemVal,
1117
27
                             /*IsSourceBuffer*/ false, Size);
1118
27
  }
1119
172
  return true;
1120
172
}
1121
1122
//===----------------------------------------------------------------------===//
1123
// evaluation of individual function calls.
1124
//===----------------------------------------------------------------------===//
1125
1126
void CStringChecker::evalCopyCommon(CheckerContext &C, const CallExpr *CE,
1127
                                    ProgramStateRef state, SizeArgExpr Size,
1128
                                    DestinationArgExpr Dest,
1129
                                    SourceArgExpr Source, bool Restricted,
1130
256
                                    bool IsMempcpy) const {
1131
256
  CurrentFunctionDescription = "memory copy function";
1132
256
1133
  // See if the size argument is zero.
1134
256
  const LocationContext *LCtx = C.getLocationContext();
1135
256
  SVal sizeVal = state->getSVal(Size.Expression, LCtx);
1136
256
  QualType sizeTy = Size.Expression->getType();
1137
256
1138
256
  ProgramStateRef stateZeroSize, stateNonZeroSize;
1139
256
  std::tie(stateZeroSize, stateNonZeroSize) =
1140
256
      assumeZero(C, state, sizeVal, sizeTy);
1141
256
1142
  // Get the value of the Dest.
1143
256
  SVal destVal = state->getSVal(Dest.Expression, LCtx);
1144
256
1145
  // If the size is zero, there won't be any actual memory access, so
1146
  // just bind the return value to the destination buffer and return.
1147
256
  if (stateZeroSize && 
!stateNonZeroSize48
) {
1148
16
    stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal);
1149
16
    C.addTransition(stateZeroSize);
1150
16
    return;
1151
16
  }
1152
240
1153
  // If the size can be nonzero, we have to check the other arguments.
1154
240
  if (stateNonZeroSize) {
1155
240
    state = stateNonZeroSize;
1156
240
1157
    // Ensure the destination is not null. If it is NULL there will be a
1158
    // NULL pointer dereference.
1159
240
    state = checkNonNull(C, state, Dest, destVal);
1160
240
    if (!state)
1161
14
      return;
1162
226
1163
    // Get the value of the Src.
1164
226
    SVal srcVal = state->getSVal(Source.Expression, LCtx);
1165
226
1166
    // Ensure the source is not null. If it is NULL there will be a
1167
    // NULL pointer dereference.
1168
226
    state = checkNonNull(C, state, Source, srcVal);
1169
226
    if (!state)
1170
16
      return;
1171
210
1172
    // Ensure the accesses are valid and that the buffers do not overlap.
1173
210
    state = CheckBufferAccess(C, state, Dest, Size, AccessKind::write);
1174
210
    state = CheckBufferAccess(C, state, Source, Size, AccessKind::read);
1175
210
1176
210
    if (Restricted)
1177
182
      state = CheckOverlap(C, state, Size, Dest, Source);
1178
210
1179
210
    if (!state)
1180
76
      return;
1181
134
1182
    // If this is mempcpy, get the byte after the last byte copied and
1183
    // bind the expr.
1184
134
    if (IsMempcpy) {
1185
      // Get the byte after the last byte copied.
1186
41
      SValBuilder &SvalBuilder = C.getSValBuilder();
1187
41
      ASTContext &Ctx = SvalBuilder.getContext();
1188
41
      QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
1189
41
      SVal DestRegCharVal =
1190
41
          SvalBuilder.evalCast(destVal, CharPtrTy, Dest.Expression->getType());
1191
41
      SVal lastElement = C.getSValBuilder().evalBinOp(
1192
41
          state, BO_Add, DestRegCharVal, sizeVal, Dest.Expression->getType());
1193
      // If we don't know how much we copied, we can at least
1194
      // conjure a return value for later.
1195
41
      if (lastElement.isUnknown())
1196
9
        lastElement = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
1197
9
                                                          C.blockCount());
1198
41
1199
      // The byte after the last byte copied is the return value.
1200
41
      state = state->BindExpr(CE, LCtx, lastElement);
1201
93
    } else {
1202
      // All other copies return the destination buffer.
1203
      // (Well, bcopy() has a void return type, but this won't hurt.)
1204
93
      state = state->BindExpr(CE, LCtx, destVal);
1205
93
    }
1206
134
1207
    // Invalidate the destination (regular invalidation without pointer-escaping
1208
    // the address of the top-level region).
1209
    // FIXME: Even if we can't perfectly model the copy, we should see if we
1210
    // can use LazyCompoundVals to copy the source values into the destination.
1211
    // This would probably remove any existing bindings past the end of the
1212
    // copied region, but that's still an improvement over blank invalidation.
1213
134
    state =
1214
134
        InvalidateBuffer(C, state, Dest.Expression, C.getSVal(Dest.Expression),
1215
134
                         /*IsSourceBuffer*/ false, Size.Expression);
1216
134
1217
    // Invalidate the source (const-invalidation without const-pointer-escaping
1218
    // the address of the top-level region).
1219
134
    state = InvalidateBuffer(C, state, Source.Expression,
1220
134
                             C.getSVal(Source.Expression),
1221
134
                             /*IsSourceBuffer*/ true, nullptr);
1222
134
1223
134
    C.addTransition(state);
1224
134
  }
1225
240
}
1226
1227
139
void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
1228
  // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
1229
  // The return value is the address of the destination buffer.
1230
139
  DestinationArgExpr Dest = {CE->getArg(0), 0};
1231
139
  SourceArgExpr Src = {CE->getArg(1), 1};
1232
139
  SizeArgExpr Size = {CE->getArg(2), 2};
1233
139
1234
139
  ProgramStateRef State = C.getState();
1235
139
1236
139
  constexpr bool IsRestricted = true;
1237
139
  constexpr bool IsMempcpy = false;
1238
139
  evalCopyCommon(C, CE, State, Size, Dest, Src, IsRestricted, IsMempcpy);
1239
139
}
1240
1241
89
void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
1242
  // void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
1243
  // The return value is a pointer to the byte following the last written byte.
1244
89
  DestinationArgExpr Dest = {CE->getArg(0), 0};
1245
89
  SourceArgExpr Src = {CE->getArg(1), 1};
1246
89
  SizeArgExpr Size = {CE->getArg(2), 2};
1247
89
1248
89
  constexpr bool IsRestricted = true;
1249
89
  constexpr bool IsMempcpy = true;
1250
89
  evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy);
1251
89
}
1252
1253
16
void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
1254
  // void *memmove(void *dst, const void *src, size_t n);
1255
  // The return value is the address of the destination buffer.
1256
16
  DestinationArgExpr Dest = {CE->getArg(0), 0};
1257
16
  SourceArgExpr Src = {CE->getArg(1), 1};
1258
16
  SizeArgExpr Size = {CE->getArg(2), 2};
1259
16
1260
16
  constexpr bool IsRestricted = false;
1261
16
  constexpr bool IsMempcpy = false;
1262
16
  evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy);
1263
16
}
1264
1265
12
void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
1266
  // void bcopy(const void *src, void *dst, size_t n);
1267
12
  SourceArgExpr Src(CE->getArg(0), 0);
1268
12
  DestinationArgExpr Dest = {CE->getArg(1), 1};
1269
12
  SizeArgExpr Size = {CE->getArg(2), 2};
1270
12
1271
12
  constexpr bool IsRestricted = false;
1272
12
  constexpr bool IsMempcpy = false;
1273
12
  evalCopyCommon(C, CE, C.getState(), Size, Dest, Src, IsRestricted, IsMempcpy);
1274
12
}
1275
1276
54
void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
1277
  // int memcmp(const void *s1, const void *s2, size_t n);
1278
54
  CurrentFunctionDescription = "memory comparison function";
1279
54
1280
54
  AnyArgExpr Left = {CE->getArg(0), 0};
1281
54
  AnyArgExpr Right = {CE->getArg(1), 1};
1282
54
  SizeArgExpr Size = {CE->getArg(2), 2};
1283
54
1284
54
  ProgramStateRef State = C.getState();
1285
54
  SValBuilder &Builder = C.getSValBuilder();
1286
54
  const LocationContext *LCtx = C.getLocationContext();
1287
54
1288
  // See if the size argument is zero.
1289
54
  SVal sizeVal = State->getSVal(Size.Expression, LCtx);
1290
54
  QualType sizeTy = Size.Expression->getType();
1291
54
1292
54
  ProgramStateRef stateZeroSize, stateNonZeroSize;
1293
54
  std::tie(stateZeroSize, stateNonZeroSize) =
1294
54
      assumeZero(C, State, sizeVal, sizeTy);
1295
54
1296
  // If the size can be zero, the result will be 0 in that case, and we don't
1297
  // have to check either of the buffers.
1298
54
  if (stateZeroSize) {
1299
28
    State = stateZeroSize;
1300
28
    State = State->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType()));
1301
28
    C.addTransition(State);
1302
28
  }
1303
54
1304
  // If the size can be nonzero, we have to check the other arguments.
1305
54
  if (stateNonZeroSize) {
1306
38
    State = stateNonZeroSize;
1307
    // If we know the two buffers are the same, we know the result is 0.
1308
    // First, get the two buffers' addresses. Another checker will have already
1309
    // made sure they're not undefined.
1310
38
    DefinedOrUnknownSVal LV =
1311
38
        State->getSVal(Left.Expression, LCtx).castAs<DefinedOrUnknownSVal>();
1312
38
    DefinedOrUnknownSVal RV =
1313
38
        State->getSVal(Right.Expression, LCtx).castAs<DefinedOrUnknownSVal>();
1314
38
1315
    // See if they are the same.
1316
38
    ProgramStateRef SameBuffer, NotSameBuffer;
1317
38
    std::tie(SameBuffer, NotSameBuffer) =
1318
38
        State->assume(Builder.evalEQ(State, LV, RV));
1319
38
1320
    // If the two arguments are the same buffer, we know the result is 0,
1321
    // and we only need to check one size.
1322
38
    if (SameBuffer && 
!NotSameBuffer22
) {
1323
6
      State = SameBuffer;
1324
6
      State = CheckBufferAccess(C, State, Left, Size, AccessKind::read);
1325
6
      if (State) {
1326
6
        State =
1327
6
            SameBuffer->BindExpr(CE, LCtx, Builder.makeZeroVal(CE->getType()));
1328
6
        C.addTransition(State);
1329
6
      }
1330
6
      return;
1331
6
    }
1332
32
1333
    // If the two arguments might be different buffers, we have to check
1334
    // the size of both of them.
1335
32
    assert(NotSameBuffer);
1336
32
    State = CheckBufferAccess(C, State, Right, Size, AccessKind::read);
1337
32
    State = CheckBufferAccess(C, State, Left, Size, AccessKind::read);
1338
32
    if (State) {
1339
      // The return value is the comparison result, which we don't know.
1340
20
      SVal CmpV = Builder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
1341
20
      State = State->BindExpr(CE, LCtx, CmpV);
1342
20
      C.addTransition(State);
1343
20
    }
1344
32
  }
1345
54
}
1346
1347
void CStringChecker::evalstrLength(CheckerContext &C,
1348
578
                                   const CallExpr *CE) const {
1349
  // size_t strlen(const char *s);
1350
578
  evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
1351
578
}
1352
1353
void CStringChecker::evalstrnLength(CheckerContext &C,
1354
108
                                    const CallExpr *CE) const {
1355
  // size_t strnlen(const char *s, size_t maxlen);
1356
108
  evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
1357
108
}
1358
1359
void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
1360
686
                                         bool IsStrnlen) const {
1361
686
  CurrentFunctionDescription = "string length function";
1362
686
  ProgramStateRef state = C.getState();
1363
686
  const LocationContext *LCtx = C.getLocationContext();
1364
686
1365
686
  if (IsStrnlen) {
1366
108
    const Expr *maxlenExpr = CE->getArg(1);
1367
108
    SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
1368
108
1369
108
    ProgramStateRef stateZeroSize, stateNonZeroSize;
1370
108
    std::tie(stateZeroSize, stateNonZeroSize) =
1371
108
      assumeZero(C, state, maxlenVal, maxlenExpr->getType());
1372
108
1373
    // If the size can be zero, the result will be 0 in that case, and we don't
1374
    // have to check the string itself.
1375
108
    if (stateZeroSize) {
1376
20
      SVal zero = C.getSValBuilder().makeZeroVal(CE->getType());
1377
20
      stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, zero);
1378
20
      C.addTransition(stateZeroSize);
1379
20
    }
1380
108
1381
    // If the size is GUARANTEED to be zero, we're done!
1382
108
    if (!stateNonZeroSize)
1383
10
      return;
1384
98
1385
    // Otherwise, record the assumption that the size is nonzero.
1386
98
    state = stateNonZeroSize;
1387
98
  }
1388
686
1389
  // Check that the string argument is non-null.
1390
676
  AnyArgExpr Arg = {CE->getArg(0), 0};
1391
676
  SVal ArgVal = state->getSVal(Arg.Expression, LCtx);
1392
676
  state = checkNonNull(C, state, Arg, ArgVal);
1393
676
1394
676
  if (!state)
1395
10
    return;
1396
666
1397
666
  SVal strLength = getCStringLength(C, state, Arg.Expression, ArgVal);
1398
666
1399
  // If the argument isn't a valid C string, there's no valid state to
1400
  // transition to.
1401
666
  if (strLength.isUndef())
1402
21
    return;
1403
645
1404
645
  DefinedOrUnknownSVal result = UnknownVal();
1405
645
1406
  // If the check is for strnlen() then bind the return value to no more than
1407
  // the maxlen value.
1408
645
  if (IsStrnlen) {
1409
83
    QualType cmpTy = C.getSValBuilder().getConditionType();
1410
83
1411
    // It's a little unfortunate to be getting this again,
1412
    // but it's not that expensive...
1413
83
    const Expr *maxlenExpr = CE->getArg(1);
1414
83
    SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
1415
83
1416
83
    Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
1417
83
    Optional<NonLoc> maxlenValNL = maxlenVal.getAs<NonLoc>();
1418
83
1419
83
    if (strLengthNL && 
maxlenValNL78
) {
1420
73
      ProgramStateRef stateStringTooLong, stateStringNotTooLong;
1421
73
1422
      // Check if the strLength is greater than the maxlen.
1423
73
      std::tie(stateStringTooLong, stateStringNotTooLong) = state->assume(
1424
73
          C.getSValBuilder()
1425
73
              .evalBinOpNN(state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
1426
73
              .castAs<DefinedOrUnknownSVal>());
1427
73
1428
73
      if (stateStringTooLong && 
!stateStringNotTooLong58
) {
1429
        // If the string is longer than maxlen, return maxlen.
1430
15
        result = *maxlenValNL;
1431
58
      } else if (stateStringNotTooLong && !stateStringTooLong) {
1432
        // If the string is shorter than maxlen, return its length.
1433
15
        result = *strLengthNL;
1434
15
      }
1435
73
    }
1436
83
1437
83
    if (result.isUnknown()) {
1438
      // If we don't have enough information for a comparison, there's
1439
      // no guarantee the full string length will actually be returned.
1440
      // All we know is the return value is the min of the string length
1441
      // and the limit. This is better than nothing.
1442
53
      result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
1443
53
                                                   C.blockCount());
1444
53
      NonLoc resultNL = result.castAs<NonLoc>();
1445
53
1446
53
      if (strLengthNL) {
1447
48
        state = state->assume(C.getSValBuilder().evalBinOpNN(
1448
48
                                  state, BO_LE, resultNL, *strLengthNL, cmpTy)
1449
48
                                  .castAs<DefinedOrUnknownSVal>(), true);
1450
48
      }
1451
53
1452
53
      if (maxlenValNL) {
1453
48
        state = state->assume(C.getSValBuilder().evalBinOpNN(
1454
48
                                  state, BO_LE, resultNL, *maxlenValNL, cmpTy)
1455
48
                                  .castAs<DefinedOrUnknownSVal>(), true);
1456
48
      }
1457
53
    }
1458
83
1459
562
  } else {
1460
    // This is a plain strlen(), not strnlen().
1461
562
    result = strLength.castAs<DefinedOrUnknownSVal>();
1462
562
1463
    // If we don't know the length of the string, conjure a return
1464
    // value, so it can be used in constraints, at least.
1465
562
    if (result.isUnknown()) {
1466
2
      result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
1467
2
                                                   C.blockCount());
1468
2
    }
1469
562
  }
1470
645
1471
  // Bind the return value.
1472
645
  assert(!result.isUnknown() && "Should have conjured a value by now");
1473
645
  state = state->BindExpr(CE, LCtx, result);
1474
645
  C.addTransition(state);
1475
645
}
1476
1477
48
void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
1478
  // char *strcpy(char *restrict dst, const char *restrict src);
1479
48
  evalStrcpyCommon(C, CE,
1480
48
                   /* ReturnEnd = */ false,
1481
48
                   /* IsBounded = */ false,
1482
48
                   /* appendK = */ ConcatFnKind::none);
1483
48
}
1484
1485
67
void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
1486
  // char *strncpy(char *restrict dst, const char *restrict src, size_t n);
1487
67
  evalStrcpyCommon(C, CE,
1488
67
                   /* ReturnEnd = */ false,
1489
67
                   /* IsBounded = */ true,
1490
67
                   /* appendK = */ ConcatFnKind::none);
1491
67
}
1492
1493
14
void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
1494
  // char *stpcpy(char *restrict dst, const char *restrict src);
1495
14
  evalStrcpyCommon(C, CE,
1496
14
                   /* ReturnEnd = */ true,
1497
14
                   /* IsBounded = */ false,
1498
14
                   /* appendK = */ ConcatFnKind::none);
1499
14
}
1500
1501
75
void CStringChecker::evalStrlcpy(CheckerContext &C, const CallExpr *CE) const {
1502
  // size_t strlcpy(char *dest, const char *src, size_t size);
1503
75
  evalStrcpyCommon(C, CE,
1504
75
                   /* ReturnEnd = */ true,
1505
75
                   /* IsBounded = */ true,
1506
75
                   /* appendK = */ ConcatFnKind::none,
1507
75
                   /* returnPtr = */ false);
1508
75
}
1509
1510
57
void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
1511
  // char *strcat(char *restrict s1, const char *restrict s2);
1512
57
  evalStrcpyCommon(C, CE,
1513
57
                   /* ReturnEnd = */ false,
1514
57
                   /* IsBounded = */ false,
1515
57
                   /* appendK = */ ConcatFnKind::strcat);
1516
57
}
1517
1518
107
void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
1519
  //char *strncat(char *restrict s1, const char *restrict s2, size_t n);
1520
107
  evalStrcpyCommon(C, CE,
1521
107
                   /* ReturnEnd = */ false,
1522
107
                   /* IsBounded = */ true,
1523
107
                   /* appendK = */ ConcatFnKind::strcat);
1524
107
}
1525
1526
42
void CStringChecker::evalStrlcat(CheckerContext &C, const CallExpr *CE) const {
1527
  // size_t strlcat(char *dst, const char *src, size_t size);
1528
  // It will append at most size - strlen(dst) - 1 bytes,
1529
  // NULL-terminating the result.
1530
42
  evalStrcpyCommon(C, CE,
1531
42
                   /* ReturnEnd = */ false,
1532
42
                   /* IsBounded = */ true,
1533
42
                   /* appendK = */ ConcatFnKind::strlcat,
1534
42
                   /* returnPtr = */ false);
1535
42
}
1536
1537
void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
1538
                                      bool ReturnEnd, bool IsBounded,
1539
                                      ConcatFnKind appendK,
1540
410
                                      bool returnPtr) const {
1541
410
  if (appendK == ConcatFnKind::none)
1542
204
    CurrentFunctionDescription = "string copy function";
1543
206
  else
1544
206
    CurrentFunctionDescription = "string concatenation function";
1545
410
1546
410
  ProgramStateRef state = C.getState();
1547
410
  const LocationContext *LCtx = C.getLocationContext();
1548
410
1549
  // Check that the destination is non-null.
1550
410
  DestinationArgExpr Dst = {CE->getArg(0), 0};
1551
410
  SVal DstVal = state->getSVal(Dst.Expression, LCtx);
1552
410
  state = checkNonNull(C, state, Dst, DstVal);
1553
410
  if (!state)
1554
23
    return;
1555
387
1556
  // Check that the source is non-null.
1557
387
  SourceArgExpr srcExpr = {CE->getArg(1), 1};
1558
387
  SVal srcVal = state->getSVal(srcExpr.Expression, LCtx);
1559
387
  state = checkNonNull(C, state, srcExpr, srcVal);
1560
387
  if (!state)
1561
20
    return;
1562
367
1563
  // Get the string length of the source.
1564
367
  SVal strLength = getCStringLength(C, state, srcExpr.Expression, srcVal);
1565
367
  Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
1566
367
1567
  // Get the string length of the destination buffer.
1568
367
  SVal dstStrLength = getCStringLength(C, state, Dst.Expression, DstVal);
1569
367
  Optional<NonLoc> dstStrLengthNL = dstStrLength.getAs<NonLoc>();
1570
367
1571
  // If the source isn't a valid C string, give up.
1572
367
  if (strLength.isUndef())
1573
25
    return;
1574
342
1575
342
  SValBuilder &svalBuilder = C.getSValBuilder();
1576
342
  QualType cmpTy = svalBuilder.getConditionType();
1577
342
  QualType sizeTy = svalBuilder.getContext().getSizeType();
1578
342
1579
  // These two values allow checking two kinds of errors:
1580
  // - actual overflows caused by a source that doesn't fit in the destination
1581
  // - potential overflows caused by a bound that could exceed the destination
1582
342
  SVal amountCopied = UnknownVal();
1583
342
  SVal maxLastElementIndex = UnknownVal();
1584
342
  const char *boundWarning = nullptr;
1585
342
1586
  // FIXME: Why do we choose the srcExpr if the access has no size?
1587
  //  Note that the 3rd argument of the call would be the size parameter.
1588
342
  SizeArgExpr SrcExprAsSizeDummy = {srcExpr.Expression, srcExpr.ArgumentIndex};
1589
342
  state = CheckOverlap(
1590
342
      C, state,
1591
259
      (IsBounded ? SizeArgExpr{CE->getArg(2), 2} : 
SrcExprAsSizeDummy83
), Dst,
1592
342
      srcExpr);
1593
342
1594
342
  if (!state)
1595
1
    return;
1596
341
1597
  // If the function is strncpy, strncat, etc... it is bounded.
1598
341
  if (IsBounded) {
1599
    // Get the max number of characters to copy.
1600
258
    SizeArgExpr lenExpr = {CE->getArg(2), 2};
1601
258
    SVal lenVal = state->getSVal(lenExpr.Expression, LCtx);
1602
258
1603
    // Protect against misdeclared strncpy().
1604
258
    lenVal =
1605
258
        svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType());
1606
258
1607
258
    Optional<NonLoc> lenValNL = lenVal.getAs<NonLoc>();
1608
258
1609
    // If we know both values, we might be able to figure out how much
1610
    // we're copying.
1611
258
    if (strLengthNL && 
lenValNL248
) {
1612
235
      switch (appendK) {
1613
200
      case ConcatFnKind::none:
1614
200
      case ConcatFnKind::strcat: {
1615
200
        ProgramStateRef stateSourceTooLong, stateSourceNotTooLong;
1616
        // Check if the max number to copy is less than the length of the src.
1617
        // If the bound is equal to the source length, strncpy won't null-
1618
        // terminate the result!
1619
200
        std::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
1620
200
            svalBuilder
1621
200
                .evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy)
1622
200
                .castAs<DefinedOrUnknownSVal>());
1623
200
1624
200
        if (stateSourceTooLong && 
!stateSourceNotTooLong153
) {
1625
          // Max number to copy is less than the length of the src, so the
1626
          // actual strLength copied is the max number arg.
1627
83
          state = stateSourceTooLong;
1628
83
          amountCopied = lenVal;
1629
83
1630
117
        } else if (!stateSourceTooLong && 
stateSourceNotTooLong47
) {
1631
          // The source buffer entirely fits in the bound.
1632
47
          state = stateSourceNotTooLong;
1633
47
          amountCopied = strLength;
1634
47
        }
1635
200
        break;
1636
200
      }
1637
35
      case ConcatFnKind::strlcat:
1638
35
        if (!dstStrLengthNL)
1639
4
          return;
1640
31
1641
        // amountCopied = min (size - dstLen - 1 , srcLen)
1642
31
        SVal freeSpace = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL,
1643
31
                                                 *dstStrLengthNL, sizeTy);
1644
31
        if (!freeSpace.getAs<NonLoc>())
1645
0
          return;
1646
31
        freeSpace =
1647
31
            svalBuilder.evalBinOp(state, BO_Sub, freeSpace,
1648
31
                                  svalBuilder.makeIntVal(1, sizeTy), sizeTy);
1649
31
        Optional<NonLoc> freeSpaceNL = freeSpace.getAs<NonLoc>();
1650
31
1651
        // While unlikely, it is possible that the subtraction is
1652
        // too complex to compute, let's check whether it succeeded.
1653
31
        if (!freeSpaceNL)
1654
0
          return;
1655
31
        SVal hasEnoughSpace = svalBuilder.evalBinOpNN(
1656
31
            state, BO_LE, *strLengthNL, *freeSpaceNL, cmpTy);
1657
31
1658
31
        ProgramStateRef TrueState, FalseState;
1659
31
        std::tie(TrueState, FalseState) =
1660
31
            state->assume(hasEnoughSpace.castAs<DefinedOrUnknownSVal>());
1661
31
1662
        // srcStrLength <= size - dstStrLength -1
1663
31
        if (TrueState && 
!FalseState23
) {
1664
14
          amountCopied = strLength;
1665
14
        }
1666
31
1667
        // srcStrLength > size - dstStrLength -1
1668
31
        if (!TrueState && 
FalseState8
) {
1669
8
          amountCopied = freeSpace;
1670
8
        }
1671
31
1672
31
        if (TrueState && 
FalseState23
)
1673
9
          amountCopied = UnknownVal();
1674
31
        break;
1675
235
      }
1676
235
    }
1677
    // We still want to know if the bound is known to be too large.
1678
254
    if (lenValNL) {
1679
241
      switch (appendK) {
1680
87
      case ConcatFnKind::strcat:
1681
        // For strncat, the check is strlen(dst) + lenVal < sizeof(dst)
1682
87
1683
        // Get the string length of the destination. If the destination is
1684
        // memory that can't have a string length, we shouldn't be copying
1685
        // into it anyway.
1686
87
        if (dstStrLength.isUndef())
1687
0
          return;
1688
87
1689
87
        if (dstStrLengthNL) {
1690
87
          maxLastElementIndex = svalBuilder.evalBinOpNN(
1691
87
              state, BO_Add, *lenValNL, *dstStrLengthNL, sizeTy);
1692
87
1693
87
          boundWarning = "Size argument is greater than the free space in the "
1694
87
                         "destination buffer";
1695
87
        }
1696
87
        break;
1697
154
      case ConcatFnKind::none:
1698
154
      case ConcatFnKind::strlcat:
1699
        // For strncpy and strlcat, this is just checking
1700
        //  that lenVal <= sizeof(dst).
1701
        // (Yes, strncpy and strncat differ in how they treat termination.
1702
        // strncat ALWAYS terminates, but strncpy doesn't.)
1703
154
1704
        // We need a special case for when the copy size is zero, in which
1705
        // case strncpy will do no work at all. Our bounds check uses n-1
1706
        // as the last element accessed, so n == 0 is problematic.
1707
154
        ProgramStateRef StateZeroSize, StateNonZeroSize;
1708
154
        std::tie(StateZeroSize, StateNonZeroSize) =
1709
154
            assumeZero(C, state, *lenValNL, sizeTy);
1710
154
1711
        // If the size is known to be zero, we're done.
1712
154
        if (StateZeroSize && 
!StateNonZeroSize14
) {
1713
9
          if (returnPtr) {
1714
5
            StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, DstVal);
1715
4
          } else {
1716
4
            if (appendK == ConcatFnKind::none) {
1717
              // strlcpy returns strlen(src)
1718
2
              StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, strLength);
1719
2
            } else {
1720
              // strlcat returns strlen(src) + strlen(dst)
1721
2
              SVal retSize = svalBuilder.evalBinOp(
1722
2
                  state, BO_Add, strLength, dstStrLength, sizeTy);
1723
2
              StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, retSize);
1724
2
            }
1725
4
          }
1726
9
          C.addTransition(StateZeroSize);
1727
9
          return;
1728
9
        }
1729
145
1730
        // Otherwise, go ahead and figure out the last element we'll touch.
1731
        // We don't record the non-zero assumption here because we can't
1732
        // be sure. We won't warn on a possible zero.
1733
145
        NonLoc one = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
1734
145
        maxLastElementIndex =
1735
145
            svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL, one, sizeTy);
1736
145
        boundWarning = "Size argument is greater than the length of the "
1737
145
                       "destination buffer";
1738
145
        break;
1739
241
      }
1740
241
    }
1741
83
  } else {
1742
    // The function isn't bounded. The amount copied should match the length
1743
    // of the source buffer.
1744
83
    amountCopied = strLength;
1745
83
  }
1746
341
1747
328
  assert(state);
1748
328
1749
  // This represents the number of characters copied into the destination
1750
  // buffer. (It may not actually be the strlen if the destination buffer
1751
  // is not terminated.)
1752
328
  SVal finalStrLength = UnknownVal();
1753
328
  SVal strlRetVal = UnknownVal();
1754
328
1755
328
  if (appendK == ConcatFnKind::none && 
!returnPtr159
) {
1756
    // strlcpy returns the sizeof(src)
1757
71
    strlRetVal = strLength;
1758
71
  }
1759
328
1760
  // If this is an appending function (strcat, strncat...) then set the
1761
  // string length to strlen(src) + strlen(dst) since the buffer will
1762
  // ultimately contain both.
1763
328
  if (appendK != ConcatFnKind::none) {
1764
    // Get the string length of the destination. If the destination is memory
1765
    // that can't have a string length, we shouldn't be copying into it anyway.
1766
169
    if (dstStrLength.isUndef())
1767
0
      return;
1768
169
1769
169
    if (appendK == ConcatFnKind::strlcat && 
dstStrLengthNL35
&&
strLengthNL34
) {
1770
34
      strlRetVal = svalBuilder.evalBinOpNN(state, BO_Add, *strLengthNL,
1771
34
                                           *dstStrLengthNL, sizeTy);
1772
34
    }
1773
169
1774
169
    Optional<NonLoc> amountCopiedNL = amountCopied.getAs<NonLoc>();
1775
169
1776
    // If we know both string lengths, we might know the final string length.
1777
169
    if (amountCopiedNL && 
dstStrLengthNL116
) {
1778
      // Make sure the two lengths together don't overflow a size_t.
1779
116
      state = checkAdditionOverflow(C, state, *amountCopiedNL, *dstStrLengthNL);
1780
116
      if (!state)
1781
0
        return;
1782
116
1783
116
      finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *amountCopiedNL,
1784
116
                                               *dstStrLengthNL, sizeTy);
1785
116
    }
1786
169
1787
    // If we couldn't get a single value for the final string length,
1788
    // we can at least bound it by the individual lengths.
1789
169
    if (finalStrLength.isUnknown()) {
1790
      // Try to get a "hypothetical" string length symbol, which we can later
1791
      // set as a real value if that turns out to be the case.
1792
53
      finalStrLength = getCStringLength(C, state, CE, DstVal, true);
1793
53
      assert(!finalStrLength.isUndef());
1794
53
1795
53
      if (Optional<NonLoc> finalStrLengthNL = finalStrLength.getAs<NonLoc>()) {
1796
52
        if (amountCopiedNL && 
appendK == ConcatFnKind::none0
) {
1797
          // we overwrite dst string with the src
1798
          // finalStrLength >= srcStrLength
1799
0
          SVal sourceInResult = svalBuilder.evalBinOpNN(
1800
0
              state, BO_GE, *finalStrLengthNL, *amountCopiedNL, cmpTy);
1801
0
          state = state->assume(sourceInResult.castAs<DefinedOrUnknownSVal>(),
1802
0
                                true);
1803
0
          if (!state)
1804
0
            return;
1805
52
        }
1806
52
1807
52
        if (dstStrLengthNL && appendK != ConcatFnKind::none) {
1808
          // we extend the dst string with the src
1809
          // finalStrLength >= dstStrLength
1810
52
          SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE,
1811
52
                                                      *finalStrLengthNL,
1812
52
                                                      *dstStrLengthNL,
1813
52
                                                      cmpTy);
1814
52
          state =
1815
52
              state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true);
1816
52
          if (!state)
1817
0
            return;
1818
159
        }
1819
52
      }
1820
53
    }
1821
159
1822
159
  } else {
1823
    // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and
1824
    // the final string length will match the input string length.
1825
159
    finalStrLength = amountCopied;
1826
159
  }
1827
328
1828
328
  SVal Result;
1829
328
1830
328
  if (returnPtr) {
1831
    // The final result of the function will either be a pointer past the last
1832
    // copied element, or a pointer to the start of the destination buffer.
1833
208
    Result = (ReturnEnd ? 
UnknownVal()14
: DstVal);
1834
106
  } else {
1835
106
    if (appendK == ConcatFnKind::strlcat || 
appendK == ConcatFnKind::none71
)
1836
      //strlcpy, strlcat
1837
106
      Result = strlRetVal;
1838
0
    else
1839
0
      Result = finalStrLength;
1840
106
  }
1841
328
1842
328
  assert(state);
1843
328
1844
  // If the destination is a MemRegion, try to check for a buffer overflow and
1845
  // record the new string length.
1846
328
  if (Optional<loc::MemRegionVal> dstRegVal =
1847
328
      DstVal.getAs<loc::MemRegionVal>()) {
1848
328
    QualType ptrTy = Dst.Expression->getType();
1849
328
1850
    // If we have an exact value on a bounded copy, use that to check for
1851
    // overflows, rather than our estimate about how much is actually copied.
1852
328
    if (Optional<NonLoc> maxLastNL = maxLastElementIndex.getAs<NonLoc>()) {
1853
230
      SVal maxLastElement =
1854
230
          svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, *maxLastNL, ptrTy);
1855
230
1856
230
      state = CheckLocation(C, state, Dst, maxLastElement, AccessKind::write);
1857
230
      if (!state)
1858
68
        return;
1859
260
    }
1860
260
1861
    // Then, if the final length is known...
1862
260
    if (Optional<NonLoc> knownStrLength = finalStrLength.getAs<NonLoc>()) {
1863
219
      SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
1864
219
          *knownStrLength, ptrTy);
1865
219
1866
      // ...and we haven't checked the bound, we'll check the actual copy.
1867
219
      if (!boundWarning) {
1868
92
        state = CheckLocation(C, state, Dst, lastElement, AccessKind::write);
1869
92
        if (!state)
1870
20
          return;
1871
199
      }
1872
199
1873
      // If this is a stpcpy-style copy, the last element is the return value.
1874
199
      if (returnPtr && 
ReturnEnd147
)
1875
10
        Result = lastElement;
1876
199
    }
1877
260
1878
    // Invalidate the destination (regular invalidation without pointer-escaping
1879
    // the address of the top-level region). This must happen before we set the
1880
    // C string length because invalidation will clear the length.
1881
    // FIXME: Even if we can't perfectly model the copy, we should see if we
1882
    // can use LazyCompoundVals to copy the source values into the destination.
1883
    // This would probably remove any existing bindings past the end of the
1884
    // string, but that's still an improvement over blank invalidation.
1885
240
    state = InvalidateBuffer(C, state, Dst.Expression, *dstRegVal,
1886
240
                             /*IsSourceBuffer*/ false, nullptr);
1887
240
1888
    // Invalidate the source (const-invalidation without const-pointer-escaping
1889
    // the address of the top-level region).
1890
240
    state = InvalidateBuffer(C, state, srcExpr.Expression, srcVal,
1891
240
                             /*IsSourceBuffer*/ true, nullptr);
1892
240
1893
    // Set the C string length of the destination, if we know it.
1894
240
    if (IsBounded && 
(appendK == ConcatFnKind::none)177
) {
1895
      // strncpy is annoying in that it doesn't guarantee to null-terminate
1896
      // the result string. If the original string didn't fit entirely inside
1897
      // the bound (including the null-terminator), we don't know how long the
1898
      // result is.
1899
88
      if (amountCopied != strLength)
1900
55
        finalStrLength = UnknownVal();
1901
88
    }
1902
240
    state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength);
1903
240
  }
1904
328
1905
240
  assert(state);
1906
240
1907
240
  if (returnPtr) {
1908
    // If this is a stpcpy-style copy, but we were unable to check for a buffer
1909
    // overflow, we still need a result. Conjure a return value.
1910
157
    if (ReturnEnd && 
Result.isUnknown()10
) {
1911
0
      Result = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
1912
0
    }
1913
157
  }
1914
  // Set the return value.
1915
240
  state = state->BindExpr(CE, LCtx, Result);
1916
240
  C.addTransition(state);
1917
240
}
1918
1919
111
void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
1920
  //int strcmp(const char *s1, const char *s2);
1921
111
  evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ false);
1922
111
}
1923
1924
115
void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
1925
  //int strncmp(const char *s1, const char *s2, size_t n);
1926
115
  evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ false);
1927
115
}
1928
1929
void CStringChecker::evalStrcasecmp(CheckerContext &C,
1930
100
    const CallExpr *CE) const {
1931
  //int strcasecmp(const char *s1, const char *s2);
1932
100
  evalStrcmpCommon(C, CE, /* IsBounded = */ false, /* IgnoreCase = */ true);
1933
100
}
1934
1935
void CStringChecker::evalStrncasecmp(CheckerContext &C,
1936
116
    const CallExpr *CE) const {
1937
  //int strncasecmp(const char *s1, const char *s2, size_t n);
1938
116
  evalStrcmpCommon(C, CE, /* IsBounded = */ true, /* IgnoreCase = */ true);
1939
116
}
1940
1941
void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
1942
442
    bool IsBounded, bool IgnoreCase) const {
1943
442
  CurrentFunctionDescription = "string comparison function";
1944
442
  ProgramStateRef state = C.getState();
1945
442
  const LocationContext *LCtx = C.getLocationContext();
1946
442
1947
  // Check that the first string is non-null
1948
442
  AnyArgExpr Left = {CE->getArg(0), 0};
1949
442
  SVal LeftVal = state->getSVal(Left.Expression, LCtx);
1950
442
  state = checkNonNull(C, state, Left, LeftVal);
1951
442
  if (!state)
1952
20
    return;
1953
422
1954
  // Check that the second string is non-null.
1955
422
  AnyArgExpr Right = {CE->getArg(1), 1};
1956
422
  SVal RightVal = state->getSVal(Right.Expression, LCtx);
1957
422
  state = checkNonNull(C, state, Right, RightVal);
1958
422
  if (!state)
1959
41
    return;
1960
381
1961
  // Get the string length of the first string or give up.
1962
381
  SVal LeftLength = getCStringLength(C, state, Left.Expression, LeftVal);
1963
381
  if (LeftLength.isUndef())
1964
0
    return;
1965
381
1966
  // Get the string length of the second string or give up.
1967
381
  SVal RightLength = getCStringLength(C, state, Right.Expression, RightVal);
1968
381
  if (RightLength.isUndef())
1969
0
    return;
1970
381
1971
  // If we know the two buffers are the same, we know the result is 0.
1972
  // First, get the two buffers' addresses. Another checker will have already
1973
  // made sure they're not undefined.
1974
381
  DefinedOrUnknownSVal LV = LeftVal.castAs<DefinedOrUnknownSVal>();
1975
381
  DefinedOrUnknownSVal RV = RightVal.castAs<DefinedOrUnknownSVal>();
1976
381
1977
  // See if they are the same.
1978
381
  SValBuilder &svalBuilder = C.getSValBuilder();
1979
381
  DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
1980
381
  ProgramStateRef StSameBuf, StNotSameBuf;
1981
381
  std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
1982
381
1983
  // If the two arguments might be the same buffer, we know the result is 0,
1984
  // and we only need to check one size.
1985
381
  if (StSameBuf) {
1986
11
    StSameBuf = StSameBuf->BindExpr(CE, LCtx,
1987
11
        svalBuilder.makeZeroVal(CE->getType()));
1988
11
    C.addTransition(StSameBuf);
1989
11
1990
    // If the two arguments are GUARANTEED to be the same, we're done!
1991
11
    if (!StNotSameBuf)
1992
5
      return;
1993
376
  }
1994
376
1995
376
  assert(StNotSameBuf);
1996
376
  state = StNotSameBuf;
1997
376
1998
  // At this point we can go about comparing the two buffers.
1999
  // For now, we only do this if they're both known string literals.
2000
376
2001
  // Attempt to extract string literals from both expressions.
2002
376
  const StringLiteral *LeftStrLiteral =
2003
376
      getCStringLiteral(C, state, Left.Expression, LeftVal);
2004
376
  const StringLiteral *RightStrLiteral =
2005
376
      getCStringLiteral(C, state, Right.Expression, RightVal);
2006
376
  bool canComputeResult = false;
2007
376
  SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
2008
376
      C.blockCount());
2009
376
2010
376
  if (LeftStrLiteral && 
RightStrLiteral375
) {
2011
370
    StringRef LeftStrRef = LeftStrLiteral->getString();
2012
370
    StringRef RightStrRef = RightStrLiteral->getString();
2013
370
2014
370
    if (IsBounded) {
2015
      // Get the max number of characters to compare.
2016
200
      const Expr *lenExpr = CE->getArg(2);
2017
200
      SVal lenVal = state->getSVal(lenExpr, LCtx);
2018
200
2019
      // If the length is known, we can get the right substrings.
2020
200
      if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) {
2021
        // Create substrings of each to compare the prefix.
2022
200
        LeftStrRef = LeftStrRef.substr(0, (size_t)len->getZExtValue());
2023
200
        RightStrRef = RightStrRef.substr(0, (size_t)len->getZExtValue());
2024
200
        canComputeResult = true;
2025
200
      }
2026
170
    } else {
2027
      // This is a normal, unbounded strcmp.
2028
170
      canComputeResult = true;
2029
170
    }
2030
370
2031
370
    if (canComputeResult) {
2032
      // Real strcmp stops at null characters.
2033
370
      size_t s1Term = LeftStrRef.find('\0');
2034
370
      if (s1Term != StringRef::npos)
2035
20
        LeftStrRef = LeftStrRef.substr(0, s1Term);
2036
370
2037
370
      size_t s2Term = RightStrRef.find('\0');
2038
370
      if (s2Term != StringRef::npos)
2039
20
        RightStrRef = RightStrRef.substr(0, s2Term);
2040
370
2041
      // Use StringRef's comparison methods to compute the actual result.
2042
185
      int compareRes = IgnoreCase ? LeftStrRef.compare_lower(RightStrRef)
2043
185
                                  : LeftStrRef.compare(RightStrRef);
2044
370
2045
      // The strcmp function returns an integer greater than, equal to, or less
2046
      // than zero, [c11, p7.24.4.2].
2047
370
      if (compareRes == 0) {
2048
110
        resultVal = svalBuilder.makeIntVal(compareRes, CE->getType());
2049
110
      }
2050
260
      else {
2051
260
        DefinedSVal zeroVal = svalBuilder.makeIntVal(0, CE->getType());
2052
        // Constrain strcmp's result range based on the result of StringRef's
2053
        // comparison methods.
2054
150
        BinaryOperatorKind op = (compareRes == 1) ? 
BO_GT110
: BO_LT;
2055
260
        SVal compareWithZero =
2056
260
          svalBuilder.evalBinOp(state, op, resultVal, zeroVal,
2057
260
              svalBuilder.getConditionType());
2058
260
        DefinedSVal compareWithZeroVal = compareWithZero.castAs<DefinedSVal>();
2059
260
        state = state->assume(compareWithZeroVal, true);
2060
260
      }
2061
370
    }
2062
370
  }
2063
376
2064
376
  state = state->BindExpr(CE, LCtx, resultVal);
2065
376
2066
  // Record this as a possible path.
2067
376
  C.addTransition(state);
2068
376
}
2069
2070
30
void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const {
2071
  //char *strsep(char **stringp, const char *delim);
2072
  // Sanity: does the search string parameter match the return type?
2073
30
  SourceArgExpr SearchStrPtr = {CE->getArg(0), 0};
2074
30
2075
30
  QualType CharPtrTy = SearchStrPtr.Expression->getType()->getPointeeType();
2076
30
  if (CharPtrTy.isNull() ||
2077
30
      CE->getType().getUnqualifiedType() != CharPtrTy.getUnqualifiedType())
2078
0
    return;
2079
30
2080
30
  CurrentFunctionDescription = "strsep()";
2081
30
  ProgramStateRef State = C.getState();
2082
30
  const LocationContext *LCtx = C.getLocationContext();
2083
30
2084
  // Check that the search string pointer is non-null (though it may point to
2085
  // a null string).
2086
30
  SVal SearchStrVal = State->getSVal(SearchStrPtr.Expression, LCtx);
2087
30
  State = checkNonNull(C, State, SearchStrPtr, SearchStrVal);
2088
30
  if (!State)
2089
5
    return;
2090
25
2091
  // Check that the delimiter string is non-null.
2092
25
  AnyArgExpr DelimStr = {CE->getArg(1), 1};
2093
25
  SVal DelimStrVal = State->getSVal(DelimStr.Expression, LCtx);
2094
25
  State = checkNonNull(C, State, DelimStr, DelimStrVal);
2095
25
  if (!State)
2096
5
    return;
2097
20
2098
20
  SValBuilder &SVB = C.getSValBuilder();
2099
20
  SVal Result;
2100
20
  if (Optional<Loc> SearchStrLoc = SearchStrVal.getAs<Loc>()) {
2101
    // Get the current value of the search string pointer, as a char*.
2102
20
    Result = State->getSVal(*SearchStrLoc, CharPtrTy);
2103
20
2104
    // Invalidate the search string, representing the change of one delimiter
2105
    // character to NUL.
2106
20
    State = InvalidateBuffer(C, State, SearchStrPtr.Expression, Result,
2107
20
                             /*IsSourceBuffer*/ false, nullptr);
2108
20
2109
    // Overwrite the search string pointer. The new value is either an address
2110
    // further along in the same string, or NULL if there are no more tokens.
2111
20
    State = State->bindLoc(*SearchStrLoc,
2112
20
        SVB.conjureSymbolVal(getTag(),
2113
20
          CE,
2114
20
          LCtx,
2115
20
          CharPtrTy,
2116
20
          C.blockCount()),
2117
20
        LCtx);
2118
0
  } else {
2119
0
    assert(SearchStrVal.isUnknown());
2120
    // Conjure a symbolic value. It's the best we can do.
2121
0
    Result = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
2122
0
  }
2123
20
2124
  // Set the return value, and finish.
2125
20
  State = State->BindExpr(CE, LCtx, Result);
2126
20
  C.addTransition(State);
2127
20
}
2128
2129
// These should probably be moved into a C++ standard library checker.
2130
7
void CStringChecker::evalStdCopy(CheckerContext &C, const CallExpr *CE) const {
2131
7
  evalStdCopyCommon(C, CE);
2132
7
}
2133
2134
void CStringChecker::evalStdCopyBackward(CheckerContext &C,
2135
5
    const CallExpr *CE) const {
2136
5
  evalStdCopyCommon(C, CE);
2137
5
}
2138
2139
void CStringChecker::evalStdCopyCommon(CheckerContext &C,
2140
12
    const CallExpr *CE) const {
2141
12
  if (!CE->getArg(2)->getType()->isPointerType())
2142
2
    return;
2143
10
2144
10
  ProgramStateRef State = C.getState();
2145
10
2146
10
  const LocationContext *LCtx = C.getLocationContext();
2147
10
2148
  // template <class _InputIterator, class _OutputIterator>
2149
  // _OutputIterator
2150
  // copy(_InputIterator __first, _InputIterator __last,
2151
  //        _OutputIterator __result)
2152
10
2153
  // Invalidate the destination buffer
2154
10
  const Expr *Dst = CE->getArg(2);
2155
10
  SVal DstVal = State->getSVal(Dst, LCtx);
2156
10
  State = InvalidateBuffer(C, State, Dst, DstVal, /*IsSource=*/false,
2157
10
      /*Size=*/nullptr);
2158
10
2159
10
  SValBuilder &SVB = C.getSValBuilder();
2160
10
2161
10
  SVal ResultVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
2162
10
  State = State->BindExpr(CE, LCtx, ResultVal);
2163
10
2164
10
  C.addTransition(State);
2165
10
}
2166
2167
159
void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const {
2168
  // void *memset(void *s, int c, size_t n);
2169
159
  CurrentFunctionDescription = "memory set function";
2170
159
2171
159
  DestinationArgExpr Buffer = {CE->getArg(0), 0};
2172
159
  AnyArgExpr CharE = {CE->getArg(1), 1};
2173
159
  SizeArgExpr Size = {CE->getArg(2), 2};
2174
159
2175
159
  ProgramStateRef State = C.getState();
2176
159
2177
  // See if the size argument is zero.
2178
159
  const LocationContext *LCtx = C.getLocationContext();
2179
159
  SVal SizeVal = C.getSVal(Size.Expression);
2180
159
  QualType SizeTy = Size.Expression->getType();
2181
159
2182
159
  ProgramStateRef ZeroSize, NonZeroSize;
2183
159
  std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy);
2184
159
2185
  // Get the value of the memory area.
2186
159
  SVal BufferPtrVal = C.getSVal(Buffer.Expression);
2187
159
2188
  // If the size is zero, there won't be any actual memory access, so
2189
  // just bind the return value to the buffer and return.
2190
159
  if (ZeroSize && 
!NonZeroSize0
) {
2191
0
    ZeroSize = ZeroSize->BindExpr(CE, LCtx, BufferPtrVal);
2192
0
    C.addTransition(ZeroSize);
2193
0
    return;
2194
0
  }
2195
159
2196
  // Ensure the memory area is not null.
2197
  // If it is NULL there will be a NULL pointer dereference.
2198
159
  State = checkNonNull(C, NonZeroSize, Buffer, BufferPtrVal);
2199
159
  if (!State)
2200
1
    return;
2201
158
2202
158
  State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write);
2203
158
  if (!State)
2204
2
    return;
2205
156
2206
  // According to the values of the arguments, bind the value of the second
2207
  // argument to the destination buffer and set string length, or just
2208
  // invalidate the destination buffer.
2209
156
  if (!memsetAux(Buffer.Expression, C.getSVal(CharE.Expression),
2210
156
                 Size.Expression, C, State))
2211
0
    return;
2212
156
2213
156
  State = State->BindExpr(CE, LCtx, BufferPtrVal);
2214
156
  C.addTransition(State);
2215
156
}
2216
2217
30
void CStringChecker::evalBzero(CheckerContext &C, const CallExpr *CE) const {
2218
30
  CurrentFunctionDescription = "memory clearance function";
2219
30
2220
30
  DestinationArgExpr Buffer = {CE->getArg(0), 0};
2221
30
  SizeArgExpr Size = {CE->getArg(1), 1};
2222
30
  SVal Zero = C.getSValBuilder().makeZeroVal(C.getASTContext().IntTy);
2223
30
2224
30
  ProgramStateRef State = C.getState();
2225
30
2226
  // See if the size argument is zero.
2227
30
  SVal SizeVal = C.getSVal(Size.Expression);
2228
30
  QualType SizeTy = Size.Expression->getType();
2229
30
2230
30
  ProgramStateRef StateZeroSize, StateNonZeroSize;
2231
30
  std::tie(StateZeroSize, StateNonZeroSize) =
2232
30
    assumeZero(C, State, SizeVal, SizeTy);
2233
30
2234
  // If the size is zero, there won't be any actual memory access,
2235
  // In this case we just return.
2236
30
  if (StateZeroSize && 
!StateNonZeroSize0
) {
2237
0
    C.addTransition(StateZeroSize);
2238
0
    return;
2239
0
  }
2240
30
2241
  // Get the value of the memory area.
2242
30
  SVal MemVal = C.getSVal(Buffer.Expression);
2243
30
2244
  // Ensure the memory area is not null.
2245
  // If it is NULL there will be a NULL pointer dereference.
2246
30
  State = checkNonNull(C, StateNonZeroSize, Buffer, MemVal);
2247
30
  if (!State)
2248
10
    return;
2249
20
2250
20
  State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write);
2251
20
  if (!State)
2252
4
    return;
2253
16
2254
16
  if (!memsetAux(Buffer.Expression, Zero, Size.Expression, C, State))
2255
0
    return;
2256
16
2257
16
  C.addTransition(State);
2258
16
}
2259
2260
//===----------------------------------------------------------------------===//
2261
// The driver method, and other Checker callbacks.
2262
//===----------------------------------------------------------------------===//
2263
2264
CStringChecker::FnCheck CStringChecker::identifyCall(const CallEvent &Call,
2265
33.9k
                                                     CheckerContext &C) const {
2266
33.9k
  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
2267
33.9k
  if (!CE)
2268
3.36k
    return nullptr;
2269
30.6k
2270
30.6k
  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
2271
30.6k
  if (!FD)
2272
19
    return nullptr;
2273
30.6k
2274
30.6k
  if (Call.isCalled(StdCopy)) {
2275
7
    return &CStringChecker::evalStdCopy;
2276
30.5k
  } else if (Call.isCalled(StdCopyBackward)) {
2277
5
    return &CStringChecker::evalStdCopyBackward;
2278
5
  }
2279
30.5k
2280
  // Pro-actively check that argument types are safe to do arithmetic upon.
2281
  // We do not want to crash if someone accidentally passes a structure
2282
  // into, say, a C++ overload of any of these functions. We could not check
2283
  // that for std::copy because they may have arguments of other types.
2284
30.5k
  for (auto I : CE->arguments()) {
2285
29.0k
    QualType T = I->getType();
2286
29.0k
    if (!T->isIntegralOrEnumerationType() && 
!T->isPointerType()19.5k
)
2287
11.5k
      return nullptr;
2288
29.0k
  }
2289
30.5k
2290
19.0k
  const FnCheck *Callback = Callbacks.lookup(Call);
2291
19.0k
  if (Callback)
2292
2.06k
    return *Callback;
2293
16.9k
2294
16.9k
  return nullptr;
2295
16.9k
}
2296
2297
33.9k
bool CStringChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
2298
33.9k
  FnCheck Callback = identifyCall(Call, C);
2299
33.9k
2300
  // If the callee isn't a string function, let another checker handle it.
2301
33.9k
  if (!Callback)
2302
31.9k
    return false;
2303
2.07k
2304
  // Check and evaluate the call.
2305
2.07k
  const auto *CE = cast<CallExpr>(Call.getOriginExpr());
2306
2.07k
  (this->*Callback)(C, CE);
2307
2.07k
2308
  // If the evaluate call resulted in no change, chain to the next eval call
2309
  // handler.
2310
  // Note, the custom CString evaluation calls assume that basic safety
2311
  // properties are held. However, if the user chooses to turn off some of these
2312
  // checks, we ignore the issues and leave the call evaluation to a generic
2313
  // handler.
2314
2.07k
  return C.isDifferent();
2315
2.07k
}
2316
2317
11.9k
void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
2318
  // Record string length for char a[] = "abc";
2319
11.9k
  ProgramStateRef state = C.getState();
2320
11.9k
2321
11.9k
  for (const auto *I : DS->decls()) {
2322
11.9k
    const VarDecl *D = dyn_cast<VarDecl>(I);
2323
11.9k
    if (!D)
2324
0
      continue;
2325
11.9k
2326
    // FIXME: Handle array fields of structs.
2327
11.9k
    if (!D->getType()->isArrayType())
2328
11.2k
      continue;
2329
706
2330
706
    const Expr *Init = D->getInit();
2331
706
    if (!Init)
2332
212
      continue;
2333
494
    if (!isa<StringLiteral>(Init))
2334
306
      continue;
2335
188
2336
188
    Loc VarLoc = state->getLValue(D, C.getLocationContext());
2337
188
    const MemRegion *MR = VarLoc.getAsRegion();
2338
188
    if (!MR)
2339
0
      continue;
2340
188
2341
188
    SVal StrVal = C.getSVal(Init);
2342
188
    assert(StrVal.isValid() && "Initializer string is unknown or undefined");
2343
188
    DefinedOrUnknownSVal strLength =
2344
188
      getCStringLength(C, state, Init, StrVal).castAs<DefinedOrUnknownSVal>();
2345
188
2346
188
    state = state->set<CStringLength>(MR, strLength);
2347
188
  }
2348
11.9k
2349
11.9k
  C.addTransition(state);
2350
11.9k
}
2351
2352
ProgramStateRef
2353
CStringChecker::checkRegionChanges(ProgramStateRef state,
2354
    const InvalidatedSymbols *,
2355
    ArrayRef<const MemRegion *> ExplicitRegions,
2356
    ArrayRef<const MemRegion *> Regions,
2357
    const LocationContext *LCtx,
2358
53.5k
    const CallEvent *Call) const {
2359
53.5k
  CStringLengthTy Entries = state->get<CStringLength>();
2360
53.5k
  if (Entries.isEmpty())
2361
52.4k
    return state;
2362
1.00k
2363
1.00k
  llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
2364
1.00k
  llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
2365
1.00k
2366
  // First build sets for the changed regions and their super-regions.
2367
1.00k
  for (ArrayRef<const MemRegion *>::iterator
2368
2.23k
      I = Regions.begin(), E = Regions.end(); I != E; 
++I1.22k
) {
2369
1.22k
    const MemRegion *MR = *I;
2370
1.22k
    Invalidated.insert(MR);
2371
1.22k
2372
1.22k
    SuperRegions.insert(MR);
2373
2.14k
    while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
2374
911
      MR = SR->getSuperRegion();
2375
911
      SuperRegions.insert(MR);
2376
911
    }
2377
1.22k
  }
2378
1.00k
2379
1.00k
  CStringLengthTy::Factory &F = state->get_context<CStringLength>();
2380
1.00k
2381
  // Then loop over the entries in the current state.
2382
1.00k
  for (CStringLengthTy::iterator I = Entries.begin(),
2383
2.20k
      E = Entries.end(); I != E; 
++I1.19k
) {
2384
1.19k
    const MemRegion *MR = I.getKey();
2385
1.19k
2386
    // Is this entry for a super-region of a changed region?
2387
1.19k
    if (SuperRegions.count(MR)) {
2388
583
      Entries = F.remove(Entries, MR);
2389
583
      continue;
2390
583
    }
2391
613
2392
    // Is this entry for a sub-region of a changed region?
2393
613
    const MemRegion *Super = MR;
2394
1.23k
    while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
2395
647
      Super = SR->getSuperRegion();
2396
647
      if (Invalidated.count(Super)) {
2397
24
        Entries = F.remove(Entries, MR);
2398
24
        break;
2399
24
      }
2400
647
    }
2401
613
  }
2402
1.00k
2403
1.00k
  return state->set<CStringLength>(Entries);
2404
1.00k
}
2405
2406
void CStringChecker::checkLiveSymbols(ProgramStateRef state,
2407
133k
    SymbolReaper &SR) const {
2408
  // Mark all symbols in our string length map as valid.
2409
133k
  CStringLengthTy Entries = state->get<CStringLength>();
2410
133k
2411
133k
  for (CStringLengthTy::iterator I = Entries.begin(), E = Entries.end();
2412
135k
      I != E; 
++I2.78k
) {
2413
2.78k
    SVal Len = I.getData();
2414
2.78k
2415
2.78k
    for (SymExpr::symbol_iterator si = Len.symbol_begin(),
2416
4.45k
        se = Len.symbol_end(); si != se; 
++si1.66k
)
2417
1.66k
      SR.markInUse(*si);
2418
2.78k
  }
2419
133k
}
2420
2421
void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
2422
133k
    CheckerContext &C) const {
2423
133k
  ProgramStateRef state = C.getState();
2424
133k
  CStringLengthTy Entries = state->get<CStringLength>();
2425
133k
  if (Entries.isEmpty())
2426
130k
    return;
2427
2.31k
2428
2.31k
  CStringLengthTy::Factory &F = state->get_context<CStringLength>();
2429
2.31k
  for (CStringLengthTy::iterator I = Entries.begin(), E = Entries.end();
2430
5.10k
      I != E; 
++I2.78k
) {
2431
2.78k
    SVal Len = I.getData();
2432
2.78k
    if (SymbolRef Sym = Len.getAsSymbol()) {
2433
1.61k
      if (SR.isDead(Sym))
2434
437
        Entries = F.remove(Entries, I.getKey());
2435
1.61k
    }
2436
2.78k
  }
2437
2.31k
2438
2.31k
  state = state->set<CStringLength>(Entries);
2439
2.31k
  C.addTransition(state);
2440
2.31k
}
2441
2442
233
void ento::registerCStringModeling(CheckerManager &Mgr) {
2443
233
  Mgr.registerChecker<CStringChecker>();
2444
233
}
2445
2446
1.56k
bool ento::shouldRegisterCStringModeling(const CheckerManager &mgr) {
2447
1.56k
  return true;
2448
1.56k
}
2449
2450
#define REGISTER_CHECKER(name)                                                 \
2451
123
  void ento::register##name(CheckerManager &mgr) {                             \
2452
123
    CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
2453
123
    checker->Filter.Check##name = true;                                        \
2454
123
    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
2455
123
  }                                                                            \
clang::ento::registerCStringNullArg(clang::ento::CheckerManager&)
Line
Count
Source
2451
65
  void ento::register##name(CheckerManager &mgr) {                             \
2452
65
    CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
2453
65
    checker->Filter.Check##name = true;                                        \
2454
65
    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
2455
65
  }                                                                            \
clang::ento::registerCStringOutOfBounds(clang::ento::CheckerManager&)
Line
Count
Source
2451
18
  void ento::register##name(CheckerManager &mgr) {                             \
2452
18
    CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
2453
18
    checker->Filter.Check##name = true;                                        \
2454
18
    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
2455
18
  }                                                                            \
clang::ento::registerCStringBufferOverlap(clang::ento::CheckerManager&)
Line
Count
Source
2451
20
  void ento::register##name(CheckerManager &mgr) {                             \
2452
20
    CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
2453
20
    checker->Filter.Check##name = true;                                        \
2454
20
    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
2455
20
  }                                                                            \
clang::ento::registerCStringNotNullTerm(clang::ento::CheckerManager&)
Line
Count
Source
2451
20
  void ento::register##name(CheckerManager &mgr) {                             \
2452
20
    CStringChecker *checker = mgr.getChecker<CStringChecker>();                \
2453
20
    checker->Filter.Check##name = true;                                        \
2454
20
    checker->Filter.CheckName##name = mgr.getCurrentCheckerName();             \
2455
20
  }                                                                            \
2456
                                                                               \
2457
250
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterCStringNullArg(clang::ento::CheckerManager const&)
Line
Count
Source
2457
134
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterCStringOutOfBounds(clang::ento::CheckerManager const&)
Line
Count
Source
2457
36
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterCStringBufferOverlap(clang::ento::CheckerManager const&)
Line
Count
Source
2457
40
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
clang::ento::shouldRegisterCStringNotNullTerm(clang::ento::CheckerManager const&)
Line
Count
Source
2457
40
  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
2458
2459
REGISTER_CHECKER(CStringNullArg)
2460
REGISTER_CHECKER(CStringOutOfBounds)
2461
REGISTER_CHECKER(CStringBufferOverlap)
2462
REGISTER_CHECKER(CStringNotNullTerm)