CStringChecker.cpp revision 0ef473f75426f0a95635d0a9dd567d27b07dbd5b
1ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//= CStringChecker.h - Checks calls to C string functions ----------*- C++ -*-//
2ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//
3ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//                     The LLVM Compiler Infrastructure
4ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//
5ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// This file is distributed under the University of Illinois Open Source
6ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// License. See LICENSE.TXT for details.
7ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//
8ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//===----------------------------------------------------------------------===//
9ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//
10ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// This defines CStringChecker, which is an assortment of checks on calls
11ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// to functions in <string.h>.
12ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//
13ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose//===----------------------------------------------------------------------===//
14ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
15a0decc9a2481f938e1675b4f7bbd58761a882a36Argyrios Kyrtzidis#include "ClangSACheckers.h"
16695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
179b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
189b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h"
20ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose#include "llvm/ADT/StringSwitch.h"
21ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
22ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseusing namespace clang;
239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
24ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
25ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rosenamespace {
26ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseclass CStringChecker : public CheckerVisitor<CStringChecker> {
27e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  BugType *BT_Null, *BT_Bounds, *BT_BoundsWrite, *BT_Overlap, *BT_NotCString;
28ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rosepublic:
29ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  CStringChecker()
30e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  : BT_Null(0), BT_Bounds(0), BT_BoundsWrite(0), BT_Overlap(0), BT_NotCString(0)
31e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  {}
32ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  static void *getTag() { static int tag; return &tag; }
33ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
349c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
35a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
36a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  void MarkLiveSymbols(const GRState *state, SymbolReaper &SR);
379c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
38e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  bool wantsRegionChangeUpdate(const GRState *state);
39a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
40a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  const GRState *EvalRegionChanges(const GRState *state,
41a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                   const MemRegion * const *Begin,
42a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                   const MemRegion * const *End,
43a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                   bool*);
44ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
45d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *);
46ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
479c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalMemcpy(CheckerContext &C, const CallExpr *CE);
489c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalMemmove(CheckerContext &C, const CallExpr *CE);
499c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalBcopy(CheckerContext &C, const CallExpr *CE);
509c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalCopyCommon(CheckerContext &C, const GRState *state,
51d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                      const Expr *Size, const Expr *Source, const Expr *Dest,
52d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                      bool Restricted = false);
53d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
549c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalMemcmp(CheckerContext &C, const CallExpr *CE);
55ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
56c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  void evalstrLength(CheckerContext &C, const CallExpr *CE);
57be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  void evalstrnLength(CheckerContext &C, const CallExpr *CE);
58be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  void evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
59be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek                           bool IsStrnlen = false);
6019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
619c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalStrcpy(CheckerContext &C, const CallExpr *CE);
620ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  void evalStrncpy(CheckerContext &C, const CallExpr *CE);
639c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalStpcpy(CheckerContext &C, const CallExpr *CE);
640ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd,
650ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek                        bool isStrncpy);
66e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
67ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Utility methods
68d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  std::pair<const GRState*, const GRState*>
6928f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  assumeZero(CheckerContext &C, const GRState *state, SVal V, QualType Ty);
70d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
71c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const GRState *setCStringLength(const GRState *state, const MemRegion *MR,
72c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                  SVal strLength);
73c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal getCStringLengthForRegion(CheckerContext &C, const GRState *&state,
74a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                 const Expr *Ex, const MemRegion *MR);
75c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal getCStringLength(CheckerContext &C, const GRState *&state,
7619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                        const Expr *Ex, SVal Buf);
7719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
78e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  const GRState *InvalidateBuffer(CheckerContext &C, const GRState *state,
79e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                  const Expr *Ex, SVal V);
80e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
8119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  bool SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
8219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                       const MemRegion *MR);
8319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
8419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  // Re-usable checks
85c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const GRState *checkNonNull(CheckerContext &C, const GRState *state,
86d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                               const Expr *S, SVal l);
87ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *CheckLocation(CheckerContext &C, const GRState *state,
88e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                               const Expr *S, SVal l,
89e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                               bool IsDestination = false);
90ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
91ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                   const Expr *Size,
92ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                   const Expr *FirstBuf,
93e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                   const Expr *SecondBuf = NULL,
94e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                   bool FirstIsDestination = false);
95ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
96d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                              const Expr *Size, const Expr *First,
97d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                              const Expr *Second);
98c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  void emitOverlapBug(CheckerContext &C, const GRState *state,
99ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                      const Stmt *First, const Stmt *Second);
100ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose};
101a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
102a5261549754fab80e30e893d8fa706bfb31e430aJordy Roseclass CStringLength {
103a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosepublic:
104a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
105a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose};
106ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose} //end anonymous namespace
107ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
108a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosenamespace clang {
1099ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
110a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  template <>
111a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  struct GRStateTrait<CStringLength>
112a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    : public GRStatePartialTrait<CStringLength::EntryMap> {
113a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    static void *GDMIndex() { return CStringChecker::getTag(); }
114a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  };
115a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis}
117a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
118695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidisstatic void RegisterCStringChecker(ExprEngine &Eng) {
119ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  Eng.registerCheck(new CStringChecker());
120ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
121ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
122695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidisvoid ento::registerCStringChecker(CheckerManager &mgr) {
123695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis  mgr.addCheckerRegisterFunction(RegisterCStringChecker);
124695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis}
125695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis
126d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
127d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose// Individual checks and utility methods.
128d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
129d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
130d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rosestd::pair<const GRState*, const GRState*>
13128f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted KremenekCStringChecker::assumeZero(CheckerContext &C, const GRState *state, SVal V,
132d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                           QualType Ty) {
133c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
134c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!val)
135d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return std::pair<const GRState*, const GRState *>(state, state);
136a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
137c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
138c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
139c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return state->assume(svalBuilder.evalEQ(state, *val, zero));
140d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
141d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
142c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekconst GRState *CStringChecker::checkNonNull(CheckerContext &C,
143d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                            const GRState *state,
144d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                            const Expr *S, SVal l) {
145d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
146d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
147d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
148a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
149d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const GRState *stateNull, *stateNonNull;
15028f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
151a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
152d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (stateNull && !stateNonNull) {
153d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    ExplodedNode *N = C.generateSink(stateNull);
154a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    if (!N)
155a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose      return NULL;
156a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
157d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (!BT_Null)
158d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      BT_Null = new BuiltinBug("API",
159a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose        "Null pointer argument in call to byte string function");
160a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
161a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    // Generate a report for this bug.
162d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null);
163a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    EnhancedBugReport *report = new EnhancedBugReport(*BT,
164a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose                                                      BT->getDescription(), N);
165a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
166a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    report->addRange(S->getSourceRange());
167a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
168a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    C.EmitReport(report);
169a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    return NULL;
170a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  }
171a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
172a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  // From here on, assume that the value is non-null.
173d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  assert(stateNonNull);
174d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  return stateNonNull;
175a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose}
176a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
177ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
178ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseconst GRState *CStringChecker::CheckLocation(CheckerContext &C,
179ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                             const GRState *state,
180e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                             const Expr *S, SVal l,
181e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                             bool IsDestination) {
182d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
183d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
184d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
185d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
186ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Check for out of bound array element access.
187ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const MemRegion *R = l.getAsRegion();
188ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!R)
189ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
190ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
191ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const ElementRegion *ER = dyn_cast<ElementRegion>(R);
192ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!ER)
193ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
194ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
195018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu  assert(ER->getValueType() == C.getASTContext().CharTy &&
196ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    "CheckLocation should only be called with char* ElementRegions");
197ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
198ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the size of the array.
199c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
200c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
201c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal Extent = svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
202ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
203ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
204ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the index of the accessed element.
20589b06584402a38933e108b66ded3a168cd492dffGabor Greif  DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
206ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
20728f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  const GRState *StInBound = state->assumeInBound(Idx, Size, true);
20828f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  const GRState *StOutBound = state->assumeInBound(Idx, Size, false);
209ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (StOutBound && !StInBound) {
210d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    ExplodedNode *N = C.generateSink(StOutBound);
211ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    if (!N)
212ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      return NULL;
213ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
214e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    BuiltinBug *BT;
215e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    if (IsDestination) {
216e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      if (!BT_BoundsWrite) {
217e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose        BT_BoundsWrite = new BuiltinBug("Out-of-bound array access",
218e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose          "Byte string function overflows destination buffer");
219e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      }
220e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      BT = static_cast<BuiltinBug*>(BT_BoundsWrite);
221e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    } else {
222e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      if (!BT_Bounds) {
223e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose        BT_Bounds = new BuiltinBug("Out-of-bound array access",
224e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose          "Byte string function accesses out-of-bound array element");
225e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      }
226e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      BT = static_cast<BuiltinBug*>(BT_Bounds);
227e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
228ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
229ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // FIXME: It would be nice to eventually make this diagnostic more clear,
230ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // e.g., by referencing the original declaration or by saying *why* this
231ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // reference is outside the range.
232ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
233ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // Generate a report for this bug.
234ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N);
235ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
236ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    report->addRange(S->getSourceRange());
237ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    C.EmitReport(report);
238ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
239ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
240ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
241ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Array bound check succeeded.  From this point forward the array bound
242ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // should always succeed.
243ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return StInBound;
244ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
245ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
246ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseconst GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
247ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                                 const GRState *state,
248ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                                 const Expr *Size,
249ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                                 const Expr *FirstBuf,
250e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                 const Expr *SecondBuf,
251e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                 bool FirstIsDestination) {
252d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
253d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
254d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
255d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
256c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
257ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  ASTContext &Ctx = C.getASTContext();
258ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
259c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
260ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
261ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
262a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  // Check that the first buffer is non-null.
263a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  SVal BufVal = state->getSVal(FirstBuf);
264c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, FirstBuf, BufVal);
265a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  if (!state)
266a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    return NULL;
267a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
268d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // Get the access length and make sure it is known.
269d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  SVal LengthVal = state->getSVal(Size);
270d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
271d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!Length)
272d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return state;
273d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
274ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Compute the offset of the last element to be accessed: size-1.
275c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
276c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
277c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                                    *Length, One, sizeTy));
278ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
279a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  // Check that the first buffer is sufficently long.
280c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
281b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose  if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
282c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
283c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                          LastOffset, PtrTy);
284e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
285ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
286b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    // If the buffer isn't large enough, abort.
287b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    if (!state)
288b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose      return NULL;
289b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose  }
290ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
291ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // If there's a second buffer, check it as well.
292ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (SecondBuf) {
293ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    BufVal = state->getSVal(SecondBuf);
294c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = checkNonNull(C, state, SecondBuf, BufVal);
295a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    if (!state)
296a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose      return NULL;
297a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
298c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
299b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
300c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
301c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                            LastOffset, PtrTy);
302b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose      state = CheckLocation(C, state, SecondBuf, BufEnd);
303b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    }
304ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
305ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
306ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Large enough or not, return this state!
307ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return state;
308ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
309ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
310ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseconst GRState *CStringChecker::CheckOverlap(CheckerContext &C,
311ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                            const GRState *state,
312d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                            const Expr *Size,
313ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                            const Expr *First,
314d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                            const Expr *Second) {
315ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Do a simple check for overlap: if the two arguments are from the same
316ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // buffer, see if the end of the first is greater than the start of the second
317ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // or vice versa.
318ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
319d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
320d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
321d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
322d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
323ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *stateTrue, *stateFalse;
324ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
325ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the buffer values and make sure they're known locations.
326c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal firstVal = state->getSVal(First);
327c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal secondVal = state->getSVal(Second);
328ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
329c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  Loc *firstLoc = dyn_cast<Loc>(&firstVal);
330c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!firstLoc)
331ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
332ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
333c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  Loc *secondLoc = dyn_cast<Loc>(&secondVal);
334c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!secondLoc)
335ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
336ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
337ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Are the two values the same?
338c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
339c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateTrue, stateFalse) =
340c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
341ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
342ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue && !stateFalse) {
343ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // If the values are known to be equal, that's automatically an overlap.
344c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    emitOverlapBug(C, stateTrue, First, Second);
345ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
346ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
347ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
34828f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  // assume the two expressions are not equal.
349ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  assert(stateFalse);
350ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  state = stateFalse;
351ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
352ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Which value comes first?
353c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  ASTContext &Ctx = svalBuilder.getContext();
354c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType cmpTy = Ctx.IntTy;
355c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
356c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                         *firstLoc, *secondLoc, cmpTy);
357c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
358c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!reverseTest)
359ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
360ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
361c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
362ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue) {
363ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    if (stateFalse) {
364ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      // If we don't know which one comes first, we can't perform this test.
365ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      return state;
366ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    } else {
367c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      // Switch the values so that firstVal is before secondVal.
368c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      Loc *tmpLoc = firstLoc;
369c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      firstLoc = secondLoc;
370c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      secondLoc = tmpLoc;
371ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
372ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      // Switch the Exprs as well, so that they still correspond.
373ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      const Expr *tmpExpr = First;
374ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      First = Second;
375ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      Second = tmpExpr;
376ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    }
377ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
378ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
379ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the length, and make sure it too is known.
380ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  SVal LengthVal = state->getSVal(Size);
381ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
382ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!Length)
383ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
384ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
385ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Convert the first buffer's start address to char*.
386ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Bail out if the cast fails.
387ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
388c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, First->getType());
389ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
390ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FirstStartLoc)
391ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
392ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
393ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Compute the end of the first buffer. Bail out if THAT fails.
394c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
395ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                 *FirstStartLoc, *Length, CharPtrTy);
396ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
397ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FirstEndLoc)
398ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
399ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
400ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Is the end of the first buffer past the start of the second buffer?
401c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
402c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                *FirstEndLoc, *secondLoc, cmpTy);
403ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
404ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!OverlapTest)
405ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
406ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
40728f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
408ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
409ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue && !stateFalse) {
410ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // Overlap!
411c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    emitOverlapBug(C, stateTrue, First, Second);
412ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
413ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
414ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
41528f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  // assume the two expressions don't overlap.
416ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  assert(stateFalse);
417ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return stateFalse;
418ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
419ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
420c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekvoid CStringChecker::emitOverlapBug(CheckerContext &C, const GRState *state,
421ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                    const Stmt *First, const Stmt *Second) {
422d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  ExplodedNode *N = C.generateSink(state);
423ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!N)
424ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return;
425ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
426ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!BT_Overlap)
427ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    BT_Overlap = new BugType("Unix API", "Improper arguments");
428ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
429ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Generate a report for this bug.
430ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  RangedBugReport *report =
431ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    new RangedBugReport(*BT_Overlap,
432ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      "Arguments must not be overlapping buffers", N);
433ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  report->addRange(First->getSourceRange());
434ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  report->addRange(Second->getSourceRange());
435ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
436ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  C.EmitReport(report);
437ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
438ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
439c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekconst GRState *CStringChecker::setCStringLength(const GRState *state,
440e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                const MemRegion *MR,
441c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                                SVal strLength) {
442c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  assert(!strLength.isUndef() && "Attempt to set an undefined string length");
443c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (strLength.isUnknown())
444e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
445e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
446e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  MR = MR->StripCasts();
447e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
448e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  switch (MR->getKind()) {
449e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::StringRegionKind:
450e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: This can happen if we strcpy() into a string region. This is
451e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // undefined [C99 6.4.5p6], but we should still warn about it.
452e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
453e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
454e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::SymbolicRegionKind:
455e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::AllocaRegionKind:
456e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::VarRegionKind:
457e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::FieldRegionKind:
458e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::ObjCIvarRegionKind:
459c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    return state->set<CStringLength>(MR, strLength);
460e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
461e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::ElementRegionKind:
462e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: Handle element regions by upper-bounding the parent region's
463e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // string length.
464e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
465e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
466e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  default:
467e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Other regions (mostly non-data) can't have a reliable C string length.
468e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // For now, just ignore the change.
469e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: These are rare but not impossible. We should output some kind of
470e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // warning for things like strcpy((char[]){'a', 0}, "b");
471e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
472e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
473e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
474e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
475c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
476a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                               const GRState *&state,
477a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                               const Expr *Ex,
478a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                               const MemRegion *MR) {
479a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // If there's a recorded length, go ahead and return it.
480a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  const SVal *Recorded = state->get<CStringLength>(MR);
481a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (Recorded)
482a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return *Recorded;
483a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
484a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Otherwise, get a new symbol and update the state.
485a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
486c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
487c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = svalBuilder.getContext().getSizeType();
488c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal strLength = svalBuilder.getMetadataSymbolVal(getTag(), MR, Ex, sizeTy, Count);
489c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = state->set<CStringLength>(MR, strLength);
490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return strLength;
491a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
492a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
493c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal CStringChecker::getCStringLength(CheckerContext &C, const GRState *&state,
49419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                                      const Expr *Ex, SVal Buf) {
49519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const MemRegion *MR = Buf.getAsRegion();
49619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  if (!MR) {
49719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // If we can't get a region, see if it's something we /know/ isn't a
49819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // C string. In the context of locations, the only time we can issue such
49919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // a warning is for labels.
50019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
501d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek      if (ExplodedNode *N = C.generateNode(state)) {
50219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        if (!BT_NotCString)
50319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose          BT_NotCString = new BuiltinBug("API",
50419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose            "Argument is not a null-terminated string.");
50519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
50619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        llvm::SmallString<120> buf;
50719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        llvm::raw_svector_ostream os(buf);
50819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        os << "Argument to byte string function is the address of the label '"
5096810630bb00ba2944cbeb54834f38f69dbddfd7fChris Lattner           << Label->getLabel()->getName()
51019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose           << "', which is not a null-terminated string";
51119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
51219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        // Generate a report for this bug.
51319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
51419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                                                          os.str(), N);
51519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
51619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        report->addRange(Ex->getSourceRange());
51719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        C.EmitReport(report);
51819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      }
51919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
52019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      return UndefinedVal();
52119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
52219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
523a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // If it's not a region and not a label, give up.
524a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
525a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
52619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
527a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // If we have a region, strip casts from it and see if we can figure out
528a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // its length. For anything we can't figure out, just return UnknownVal.
529a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  MR = MR->StripCasts();
530a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
531a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  switch (MR->getKind()) {
532a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::StringRegionKind: {
533a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Modifying the contents of string regions is undefined [C99 6.4.5p6],
534a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // so we can assume that the byte length is the correct C string length.
535c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SValBuilder &svalBuilder = C.getSValBuilder();
536c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    QualType sizeTy = svalBuilder.getContext().getSizeType();
537c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
538c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
539a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
540a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::SymbolicRegionKind:
541a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::AllocaRegionKind:
542a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::VarRegionKind:
543a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::FieldRegionKind:
544a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::ObjCIvarRegionKind:
545c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    return getCStringLengthForRegion(C, state, Ex, MR);
546a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::CompoundLiteralRegionKind:
547a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: Can we track this? Is it necessary?
548a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
549a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::ElementRegionKind:
550a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: How can we handle this? It's not good enough to subtract the
551a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // offset from the base string length; consider "123\x00567" and &a[5].
552a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
553a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  default:
554a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Other regions (mostly non-data) can't have a reliable C string length.
555a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // In this case, an error is emitted and UndefinedVal is returned.
556a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // The caller should always be prepared to handle this case.
557d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    if (ExplodedNode *N = C.generateNode(state)) {
558a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (!BT_NotCString)
559a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        BT_NotCString = new BuiltinBug("API",
560a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose          "Argument is not a null-terminated string.");
561a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
562a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      llvm::SmallString<120> buf;
563a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      llvm::raw_svector_ostream os(buf);
564a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
565a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      os << "Argument to byte string function is ";
566a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
567a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (SummarizeRegion(os, C.getASTContext(), MR))
568a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        os << ", which is not a null-terminated string";
569a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      else
570a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        os << "not a null-terminated string";
571a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
572a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      // Generate a report for this bug.
573a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
574a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                                        os.str(), N);
575a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
576a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      report->addRange(Ex->getSourceRange());
577a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      C.EmitReport(report);
57819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
57919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
580a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UndefinedVal();
58119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
58219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
58319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
584e64f311c11a8751867c2538807054f4817c1f5cbJordy Roseconst GRState *CStringChecker::InvalidateBuffer(CheckerContext &C,
585e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                const GRState *state,
586e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                const Expr *E, SVal V) {
587e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  Loc *L = dyn_cast<Loc>(&V);
588e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!L)
589e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
590e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
591e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
592e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // some assumptions about the value that CFRefCount can't. Even so, it should
593e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // probably be refactored.
594e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
595e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    const MemRegion *R = MR->getRegion()->StripCasts();
596e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
597e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Are we dealing with an ElementRegion?  If so, we should be invalidating
598e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // the super-region.
599e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
600e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      R = ER->getSuperRegion();
601e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // FIXME: What about layers of ElementRegions?
602e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
603e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
604e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Invalidate this region.
605e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
6062534528c22260211a073e192c38d0db84c70c327Ted Kremenek    return state->invalidateRegion(R, E, Count, NULL);
607e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
608e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
609e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If we have a non-region value by chance, just remove the binding.
610e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // FIXME: is this necessary or correct? This handles the non-Region
611e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  //  cases.  Is it ever valid to store to these?
612e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  return state->unbindLoc(*L);
613e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
614e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
61519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rosebool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
61619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                                     const MemRegion *MR) {
61719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
61819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  if (!TR)
61919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return false;
62019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
62119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  switch (TR->getKind()) {
62219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::FunctionTextRegionKind: {
62319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    const FunctionDecl *FD = cast<FunctionTextRegion>(TR)->getDecl();
62419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    if (FD)
62519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      os << "the address of the function '" << FD << "'";
62619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    else
62719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      os << "the address of a function";
62819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
62919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
63019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::BlockTextRegionKind:
63119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    os << "block text";
63219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
63319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::BlockDataRegionKind:
63419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    os << "a block";
63519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
63619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::CXXThisRegionKind:
63702fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu  case MemRegion::CXXTempObjectRegionKind:
63802fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu    os << "a C++ temp object of type " << TR->getValueType().getAsString();
63919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
64019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::VarRegionKind:
641018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    os << "a variable of type" << TR->getValueType().getAsString();
64219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
64319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::FieldRegionKind:
644018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    os << "a field of type " << TR->getValueType().getAsString();
64519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
64619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::ObjCIvarRegionKind:
647018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    os << "an instance variable of type " << TR->getValueType().getAsString();
64819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
64919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  default:
65019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return false;
65119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
65219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
65319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
654d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
6559c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek// evaluation of individual function calls.
656d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
657ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
6589c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalCopyCommon(CheckerContext &C, const GRState *state,
659d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                    const Expr *Size, const Expr *Dest,
660d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                    const Expr *Source, bool Restricted) {
661d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // See if the size argument is zero.
662c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal sizeVal = state->getSVal(Size);
663c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
664d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
665c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const GRState *stateZeroSize, *stateNonZeroSize;
666c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateZeroSize, stateNonZeroSize) = assumeZero(C, state, sizeVal, sizeTy);
667d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
668d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size is zero, there won't be any actual memory access.
669c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateZeroSize)
670c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    C.addTransition(stateZeroSize);
671d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
672d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be nonzero, we have to check the other arguments.
673c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateNonZeroSize) {
674c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = stateNonZeroSize;
675e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    state = CheckBufferAccess(C, state, Size, Dest, Source,
676e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                              /* FirstIsDst = */ true);
677d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (Restricted)
678d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckOverlap(C, state, Size, Dest, Source);
679e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
680e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    if (state) {
681e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // Invalidate the destination.
682e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // FIXME: Even if we can't perfectly model the copy, we should see if we
683e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // can use LazyCompoundVals to copy the source values into the destination.
684e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // This would probably remove any existing bindings past the end of the
685e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // copied region, but that's still an improvement over blank invalidation.
686e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
687d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      C.addTransition(state);
688e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
689d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  }
690ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
691ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
692ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
6939c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) {
694d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
695d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // The return value is the address of the destination buffer.
696d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const Expr *Dest = CE->getArg(0);
697ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *state = C.getState();
698d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  state = state->BindExpr(CE, state->getSVal(Dest));
6999c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1), true);
700d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
701ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
7029c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) {
703d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void *memmove(void *dst, const void *src, size_t n);
704ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // The return value is the address of the destination buffer.
705d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const Expr *Dest = CE->getArg(0);
706d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const GRState *state = C.getState();
707d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  state = state->BindExpr(CE, state->getSVal(Dest));
7089c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1));
709ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
710ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
7119c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) {
712d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void bcopy(const void *src, void *dst, size_t n);
7139c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalCopyCommon(C, C.getState(), CE->getArg(2), CE->getArg(1), CE->getArg(0));
714d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
715d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
7169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) {
717bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  // int memcmp(const void *s1, const void *s2, size_t n);
718bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Left = CE->getArg(0);
719bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Right = CE->getArg(1);
720bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Size = CE->getArg(2);
721bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
722bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const GRState *state = C.getState();
723c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
724bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
725d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // See if the size argument is zero.
726c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal sizeVal = state->getSVal(Size);
727c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
728bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
729c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const GRState *stateZeroSize, *stateNonZeroSize;
730c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateZeroSize, stateNonZeroSize) =
731c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    assumeZero(C, state, sizeVal, sizeTy);
732bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
733d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be zero, the result will be 0 in that case, and we don't
734d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // have to check either of the buffers.
735c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateZeroSize) {
736c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = stateZeroSize;
737c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
738d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    C.addTransition(state);
739bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  }
740bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
741d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be nonzero, we have to check the other arguments.
742c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateNonZeroSize) {
743c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = stateNonZeroSize;
744d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // If we know the two buffers are the same, we know the result is 0.
745d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // First, get the two buffers' addresses. Another checker will have already
746d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // made sure they're not undefined.
747d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
748d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
749d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
750d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // See if they are the same.
751c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
752d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    const GRState *StSameBuf, *StNotSameBuf;
75328f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek    llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
754d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
755d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // If the two arguments might be the same buffer, we know the result is zero,
756d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // and we only need to check one size.
757d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (StSameBuf) {
758d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = StSameBuf;
759d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckBufferAccess(C, state, Size, Left);
760d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      if (state) {
761c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
762d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        C.addTransition(state);
763d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      }
764d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    }
765bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
766d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // If the two arguments might be different buffers, we have to check the
767d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // size of both of them.
768d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (StNotSameBuf) {
769d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = StNotSameBuf;
770d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckBufferAccess(C, state, Size, Left, Right);
771d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      if (state) {
772d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        // The return value is the comparison result, which we don't know.
773d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
774c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
775d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        state = state->BindExpr(CE, CmpV);
776d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        C.addTransition(state);
777d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      }
778d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    }
779d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  }
780bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose}
781bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
782c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekvoid CStringChecker::evalstrLength(CheckerContext &C, const CallExpr *CE) {
78319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  // size_t strlen(const char *s);
784be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
785be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek}
786be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
787be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenekvoid CStringChecker::evalstrnLength(CheckerContext &C, const CallExpr *CE) {
788be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  // size_t strnlen(const char *s, size_t maxlen);
789be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
790be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek}
791be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
792be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenekvoid CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
793be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek                                         bool IsStrnlen) {
79419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const GRState *state = C.getState();
79519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const Expr *Arg = CE->getArg(0);
79619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  SVal ArgVal = state->getSVal(Arg);
79719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
79819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  // Check that the argument is non-null.
799c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, Arg, ArgVal);
80019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
80119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  if (state) {
802c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal strLength = getCStringLength(C, state, Arg, ArgVal);
803a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
804a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // If the argument isn't a valid C string, there's no valid state to
805a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // transition to.
806c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    if (strLength.isUndef())
807a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      return;
808a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
809be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    // If the check is for strnlen() then bind the return value to no more than
810be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    // the maxlen value.
811be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    if (IsStrnlen) {
812be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      const Expr *maxlenExpr = CE->getArg(1);
813be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      SVal maxlenVal = state->getSVal(maxlenExpr);
814be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
815be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
816be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
817be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
818be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      QualType cmpTy = C.getSValBuilder().getContext().IntTy;
819be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      const GRState *stateTrue, *stateFalse;
820be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
821be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      // Check if the strLength is greater than or equal to the maxlen
822be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      llvm::tie(stateTrue, stateFalse) =
823be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek        state->assume(cast<DefinedOrUnknownSVal>
824be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek                      (C.getSValBuilder().evalBinOpNN(state, BO_GE,
825be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek                                                      *strLengthNL, *maxlenValNL,
826be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek                                                      cmpTy)));
827be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
828be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      // If the strLength is greater than or equal to the maxlen, set strLength
829be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      // to maxlen
830be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      if (stateTrue && !stateFalse) {
831be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek        strLength = maxlenVal;
832be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek      }
833be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    }
834be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
835c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    // If getCStringLength couldn't figure out the length, conjure a return
836a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // value, so it can be used in constraints, at least.
837c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    if (strLength.isUnknown()) {
838a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
839c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      strLength = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
84019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
841a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
842a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Bind the return value.
843c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = state->BindExpr(CE, strLength);
844a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    C.addTransition(state);
84519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
84619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
84719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
8489c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) {
849e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // char *strcpy(char *restrict dst, const char *restrict src);
8500ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  evalStrcpyCommon(C, CE, /* returnEnd = */ false, /* isStrncpy = */ false);
8510ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek}
8520ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
8530ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenekvoid CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) {
8540ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  // char *strcpy(char *restrict dst, const char *restrict src);
8550ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  evalStrcpyCommon(C, CE, /* returnEnd = */ false, /* isStrncpy = */ true);
856e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
857e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
8589c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) {
859e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // char *stpcpy(char *restrict dst, const char *restrict src);
8600ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  evalStrcpyCommon(C, CE, /* returnEnd = */ true, /* isStrncpy = */ false);
861e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
862e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
8639c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
8640ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek                                      bool returnEnd, bool isStrncpy) {
865e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  const GRState *state = C.getState();
866e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
867e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Check that the destination is non-null
868e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  const Expr *Dst = CE->getArg(0);
869e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  SVal DstVal = state->getSVal(Dst);
870e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
871c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, Dst, DstVal);
872e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!state)
873e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
874e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
875e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Check that the source is non-null.
876c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const Expr *srcExpr = CE->getArg(1);
877c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal srcVal = state->getSVal(srcExpr);
878c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, srcExpr, srcVal);
879e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!state)
880e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
881e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
882e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Get the string length of the source.
883c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal strLength = getCStringLength(C, state, srcExpr, srcVal);
884e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
885e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If the source isn't a valid C string, give up.
886c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (strLength.isUndef())
887e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
888e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
8890ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  if (isStrncpy) {
8900ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    // Get the max number of characters to copy
8910ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    const Expr *lenExpr = CE->getArg(2);
8920ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    SVal lenVal = state->getSVal(lenExpr);
8930ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
8940ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
8950ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
8960ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
8970ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    QualType cmpTy = C.getSValBuilder().getContext().IntTy;
8980ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    const GRState *stateTrue, *stateFalse;
8990ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
9000ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    // Check if the max number to copy is less than the length of the src
9010ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    llvm::tie(stateTrue, stateFalse) =
9020ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek      state->assume(cast<DefinedOrUnknownSVal>
9030ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek                    (C.getSValBuilder().evalBinOpNN(state, BO_GT,
9040ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek                                                    *strLengthNL, *lenValNL,
9050ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek                                                    cmpTy)));
9060ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
9070ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    if (stateTrue) {
9080ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek      // Max number to copy is less than the length of the src, so the actual
9090ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek      // strLength copied is the max number arg.
9100ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek      strLength = lenVal;
9110ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    }
9120ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  }
9130ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
914c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal Result = (returnEnd ? UnknownVal() : DstVal);
915e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
916e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If the destination is a MemRegion, try to check for a buffer overflow and
917e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // record the new string length.
918c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
919e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // If the length is known, we can check for an overflow.
920c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&strLength)) {
921c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      SVal lastElement =
922c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        C.getSValBuilder().evalBinOpLN(state, BO_Add, *dstRegVal,
923c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                       *knownStrLength, Dst->getType());
924e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
925c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      state = CheckLocation(C, state, Dst, lastElement, /* IsDst = */ true);
926e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      if (!state)
927e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose        return;
928e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
929e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // If this is a stpcpy-style copy, the last element is the return value.
930c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      if (returnEnd)
931c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        Result = lastElement;
932e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
933e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
934e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Invalidate the destination. This must happen before we set the C string
935e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // length because invalidation will clear the length.
936e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: Even if we can't perfectly model the copy, we should see if we
937e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // can use LazyCompoundVals to copy the source values into the destination.
938e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // This would probably remove any existing bindings past the end of the
939e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // string, but that's still an improvement over blank invalidation.
940c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = InvalidateBuffer(C, state, Dst, *dstRegVal);
941e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
942e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Set the C string length of the destination.
943c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = setCStringLength(state, dstRegVal->getRegion(), strLength);
944e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
945e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
946e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If this is a stpcpy-style copy, but we were unable to check for a buffer
947e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // overflow, we still need a result. Conjure a return value.
948c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (returnEnd && Result.isUnknown()) {
949c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SValBuilder &svalBuilder = C.getSValBuilder();
950e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
951c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    strLength = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
952e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
953e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
954e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Set the return value.
955e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  state = state->BindExpr(CE, Result);
956e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  C.addTransition(state);
957e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
958e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
959d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
960a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose// The driver method, and other Checker callbacks.
961d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
962ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
9639c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekbool CStringChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
964ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the callee.  All the functions we care about are C functions
965ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // with simple identifiers.
966ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const GRState *state = C.getState();
967ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const Expr *Callee = CE->getCallee();
968ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
969ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
970ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FD)
971ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return false;
972ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
973ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the name of the callee. If it's a builtin, strip off the prefix.
97490d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor  IdentifierInfo *II = FD->getIdentifier();
97590d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor  if (!II)   // if no identifier, not a simple C function
97690d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor    return false;
97790d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor  llvm::StringRef Name = II->getName();
978ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (Name.startswith("__builtin_"))
979ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    Name = Name.substr(10);
980ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
9819c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
9829c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
9839c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
9849c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
9859c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
9860ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
9879c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
988c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    .Case("strlen", &CStringChecker::evalstrLength)
989be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    .Case("strnlen", &CStringChecker::evalstrnLength)
9909c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Case("bcopy", &CStringChecker::evalBcopy)
991ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    .Default(NULL);
992ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
993d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the callee isn't a string function, let another checker handle it.
9949c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  if (!evalFunction)
995ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return false;
996ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
997d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // Check and evaluate the call.
9989c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  (this->*evalFunction)(C, CE);
999ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return true;
1000ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
1001a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1002a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosevoid CStringChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
1003a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Record string length for char a[] = "abc";
1004a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  const GRState *state = C.getState();
1005a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1006a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
1007a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1008a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const VarDecl *D = dyn_cast<VarDecl>(*I);
1009a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!D)
1010a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1011a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1012a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: Handle array fields of structs.
1013a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!D->getType()->isArrayType())
1014a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1015a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1016a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const Expr *Init = D->getInit();
1017a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!Init)
1018a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1019a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!isa<StringLiteral>(Init))
1020a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1021a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1022a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
1023a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *MR = VarLoc.getAsRegion();
1024a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!MR)
1025a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1026a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1027a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal StrVal = state->getSVal(Init);
1028a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    assert(StrVal.isValid() && "Initializer string is unknown or undefined");
1029c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    DefinedOrUnknownSVal strLength
1030c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
1031a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1032c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = state->set<CStringLength>(MR, strLength);
1033a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1034a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1035a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  C.addTransition(state);
1036a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1037a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1038e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekbool CStringChecker::wantsRegionChangeUpdate(const GRState *state) {
1039a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1040a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  return !Entries.isEmpty();
1041a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1042a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1043a5261549754fab80e30e893d8fa706bfb31e430aJordy Roseconst GRState *CStringChecker::EvalRegionChanges(const GRState *state,
1044a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                                 const MemRegion * const *Begin,
1045a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                                 const MemRegion * const *End,
1046a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                                 bool *) {
1047a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1048a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (Entries.isEmpty())
1049a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return state;
1050a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1051a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
1052a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
1053a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1054a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // First build sets for the changed regions and their super-regions.
1055a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for ( ; Begin != End; ++Begin) {
1056a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *MR = *Begin;
1057a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    Invalidated.insert(MR);
1058a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1059a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SuperRegions.insert(MR);
1060a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
1061a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      MR = SR->getSuperRegion();
1062a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      SuperRegions.insert(MR);
1063a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1064a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1065a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1066a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1067a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1068a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Then loop over the entries in the current state.
1069a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(),
1070a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       E = Entries.end(); I != E; ++I) {
1071a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *MR = I.getKey();
1072a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1073a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Is this entry for a super-region of a changed region?
1074a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (SuperRegions.count(MR)) {
10753baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      Entries = F.remove(Entries, MR);
1076a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1077a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1078a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1079a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Is this entry for a sub-region of a changed region?
1080a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *Super = MR;
1081a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
1082a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      Super = SR->getSuperRegion();
1083a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (Invalidated.count(Super)) {
10843baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        Entries = F.remove(Entries, MR);
1085a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        break;
1086a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      }
1087a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1088a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1089a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1090a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  return state->set<CStringLength>(Entries);
1091a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1092a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1093a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosevoid CStringChecker::MarkLiveSymbols(const GRState *state, SymbolReaper &SR) {
1094a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Mark all symbols in our string length map as valid.
1095a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1096a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1097a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1098a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1099a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal Len = I.getData();
1100a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (SymbolRef Sym = Len.getAsSymbol())
1101a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      SR.markInUse(Sym);
1102a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1103a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1104a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
11059c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalDeadSymbols(CheckerContext &C, SymbolReaper &SR) {
1106a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (!SR.hasDeadSymbols())
1107a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return;
1108a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1109a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  const GRState *state = C.getState();
1110a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1111a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (Entries.isEmpty())
1112a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return;
1113a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1114a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1115a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1116a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1117a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal Len = I.getData();
1118a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (SymbolRef Sym = Len.getAsSymbol()) {
1119a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (SR.isDead(Sym))
11203baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        Entries = F.remove(Entries, I.getKey());
1121a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1122a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1123a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1124a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  state = state->set<CStringLength>(Entries);
1125d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  C.generateNode(state);
1126a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1127