1c800f68f8e61007a6dc5dc8213629fb423e76cd9Anna Zaks//= CStringChecker.cpp - 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"
16ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h"
17695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
18183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
2018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
21ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose#include "llvm/ADT/StringSwitch.h"
22ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
23ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Roseusing namespace clang;
249ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
25ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
26ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rosenamespace {
27ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CStringChecker : public Checker< eval::Call,
28183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         check::PreStmt<DeclStmt>,
29183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         check::LiveSymbols,
30183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         check::DeadSymbols,
31183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         check::RegionChanges
32183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         > {
339e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  mutable llvm::OwningPtr<BugType> BT_Null, BT_Bounds,
34d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                   BT_Overlap, BT_NotCString,
35d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                   BT_AdditionOverflow;
369e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  mutable const char *CurrentFunctionDescription;
379e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
38ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rosepublic:
39ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  static void *getTag() { static int tag; return &tag; }
40ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
41183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  bool evalCall(const CallExpr *CE, CheckerContext &C) const;
42183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
4318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void checkLiveSymbols(const ProgramState *state, SymbolReaper &SR) const;
44183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
4518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  bool wantsRegionChangeUpdate(const ProgramState *state) const;
46a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
4718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *
4818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    checkRegionChanges(const ProgramState *state,
4918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       const StoreManager::InvalidatedSymbols *,
50537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                       ArrayRef<const MemRegion *> ExplicitRegions,
51537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                       ArrayRef<const MemRegion *> Regions) const;
52ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
53183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  typedef void (CStringChecker::*FnCheck)(CheckerContext &,
54183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                          const CallExpr *) const;
55ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
56183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalMemcpy(CheckerContext &C, const CallExpr *CE) const;
57b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  void evalMempcpy(CheckerContext &C, const CallExpr *CE) const;
58183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
59183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
60b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
6118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const ProgramState *state,
6218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const Expr *Size,
6318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const Expr *Source,
6418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const Expr *Dest,
65b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                      bool Restricted = false,
66b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                      bool IsMempcpy = false) const;
67d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
68183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalMemcmp(CheckerContext &C, const CallExpr *CE) const;
69ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
70183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
71183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
7218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void evalstrLengthCommon(CheckerContext &C,
7318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                           const CallExpr *CE,
74183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                           bool IsStrnlen = false) const;
7519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
76183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalStrcpy(CheckerContext &C, const CallExpr *CE) const;
77183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalStrncpy(CheckerContext &C, const CallExpr *CE) const;
78183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void evalStpcpy(CheckerContext &C, const CallExpr *CE) const;
7918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void evalStrcpyCommon(CheckerContext &C,
8018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        const CallExpr *CE,
8118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        bool returnEnd,
8218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        bool isBounded,
8318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        bool isAppending) const;
84067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
85067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  void evalStrcat(CheckerContext &C, const CallExpr *CE) const;
86067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  void evalStrncat(CheckerContext &C, const CallExpr *CE) const;
87e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
88318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
89357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani  void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
90bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani  void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
91454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani  void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const;
9218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void evalStrcmpCommon(CheckerContext &C,
9318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        const CallExpr *CE,
9418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        bool isBounded = false,
9518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        bool ignoreCase = false) const;
96318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
97ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Utility methods
9818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  std::pair<const ProgramState*, const ProgramState*>
99183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static assumeZero(CheckerContext &C,
10018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                    const ProgramState *state, SVal V, QualType Ty);
101183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
10218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  static const ProgramState *setCStringLength(const ProgramState *state,
10318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                              const MemRegion *MR,
10418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                              SVal strLength);
105183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static SVal getCStringLengthForRegion(CheckerContext &C,
10618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const ProgramState *&state,
10718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *Ex,
10818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const MemRegion *MR,
109d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                        bool hypothetical);
11018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  SVal getCStringLength(CheckerContext &C,
11118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        const ProgramState *&state,
11218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        const Expr *Ex,
11318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                        SVal Buf,
114d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                        bool hypothetical = false) const;
11519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
116318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const StringLiteral *getCStringLiteral(CheckerContext &C,
11718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                         const ProgramState *&state,
118318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani                                         const Expr *expr,
119318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani                                         SVal val) const;
120318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
12118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  static const ProgramState *InvalidateBuffer(CheckerContext &C,
12218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                              const ProgramState *state,
12318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                              const Expr *Ex, SVal V);
124e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1259c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
126183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                              const MemRegion *MR);
12719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
12819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  // Re-usable checks
12918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *checkNonNull(CheckerContext &C,
13018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const ProgramState *state,
13118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const Expr *S,
13218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   SVal l) const;
13318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *CheckLocation(CheckerContext &C,
13418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    const ProgramState *state,
13518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    const Expr *S,
13618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    SVal l,
13718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    const char *message = NULL) const;
13818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *CheckBufferAccess(CheckerContext &C,
13918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const ProgramState *state,
14018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *Size,
14118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *FirstBuf,
14218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *SecondBuf,
14318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const char *firstMessage = NULL,
14418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const char *secondMessage = NULL,
14518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        bool WarnAboutSize = false) const;
14618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek
14718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *CheckBufferAccess(CheckerContext &C,
14818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const ProgramState *state,
14918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *Size,
15018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const Expr *Buf,
15118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        const char *message = NULL,
15218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                        bool WarnAboutSize = false) const {
1539e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    // This is a convenience override.
1545e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
1555e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose                             WarnAboutSize);
1569e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  }
15718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *CheckOverlap(CheckerContext &C,
15818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const ProgramState *state,
15918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const Expr *Size,
16018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const Expr *First,
16118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                   const Expr *Second) const;
16218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void emitOverlapBug(CheckerContext &C,
16318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const ProgramState *state,
16418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const Stmt *First,
16518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                      const Stmt *Second) const;
16618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek
16718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *checkAdditionOverflow(CheckerContext &C,
16818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                            const ProgramState *state,
16918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                            NonLoc left,
17018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                            NonLoc right) const;
171ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose};
172a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
173a5261549754fab80e30e893d8fa706bfb31e430aJordy Roseclass CStringLength {
174a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosepublic:
175a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
176a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose};
177ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose} //end anonymous namespace
178ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
179a5261549754fab80e30e893d8fa706bfb31e430aJordy Rosenamespace clang {
1809ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
181a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  template <>
18218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  struct ProgramStateTrait<CStringLength>
18318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    : public ProgramStatePartialTrait<CStringLength::EntryMap> {
184a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    static void *GDMIndex() { return CStringChecker::getTag(); }
185a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  };
186a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1875a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis}
188a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
189d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
190d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose// Individual checks and utility methods.
191d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
192d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
19318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekstd::pair<const ProgramState*, const ProgramState*>
19418c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCStringChecker::assumeZero(CheckerContext &C, const ProgramState *state, SVal V,
195d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                           QualType Ty) {
196c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
197c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!val)
19818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    return std::pair<const ProgramState*, const ProgramState *>(state, state);
199a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
200c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
201c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
202c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return state->assume(svalBuilder.evalEQ(state, *val, zero));
203d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
204d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
20518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::checkNonNull(CheckerContext &C,
20618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                            const ProgramState *state,
207183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                            const Expr *S, SVal l) const {
208d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
209d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
210d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
211a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
21218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *stateNull, *stateNonNull;
21328f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
214a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
215d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (stateNull && !stateNonNull) {
216d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    ExplodedNode *N = C.generateSink(stateNull);
217a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    if (!N)
218a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose      return NULL;
219a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
220d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (!BT_Null)
221183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      BT_Null.reset(new BuiltinBug("API",
222183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis        "Null pointer argument in call to byte string function"));
223a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
2249e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    llvm::SmallString<80> buf;
2259e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    llvm::raw_svector_ostream os(buf);
2269e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    assert(CurrentFunctionDescription);
2279e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    os << "Null pointer argument in call to " << CurrentFunctionDescription;
2289e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
229a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    // Generate a report for this bug.
230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null.get());
231e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    BugReport *report = new BugReport(*BT, os.str(), N);
232a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
233a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    report->addRange(S->getSourceRange());
23450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S));
235a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    C.EmitReport(report);
236a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    return NULL;
237a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  }
238a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
239a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  // From here on, assume that the value is non-null.
240d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  assert(stateNonNull);
241d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  return stateNonNull;
242a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose}
243a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
244ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
24518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::CheckLocation(CheckerContext &C,
24618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                             const ProgramState *state,
247e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                             const Expr *S, SVal l,
2489e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose                                             const char *warningMsg) const {
249d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
250d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
251d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
252d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
253ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Check for out of bound array element access.
254ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const MemRegion *R = l.getAsRegion();
255ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!R)
256ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
257ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
258ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const ElementRegion *ER = dyn_cast<ElementRegion>(R);
259ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!ER)
260ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
261ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
262018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu  assert(ER->getValueType() == C.getASTContext().CharTy &&
263ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    "CheckLocation should only be called with char* ElementRegions");
264ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
265ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the size of the array.
266c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
267c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
2681e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose  SVal Extent =
2691e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose    svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
270ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
271ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
272ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the index of the accessed element.
27389b06584402a38933e108b66ded3a168cd492dffGabor Greif  DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
274ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
27518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *StInBound = state->assumeInBound(Idx, Size, true);
27618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *StOutBound = state->assumeInBound(Idx, Size, false);
277ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (StOutBound && !StInBound) {
278d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    ExplodedNode *N = C.generateSink(StOutBound);
279ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    if (!N)
280ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      return NULL;
281ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
2829e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    if (!BT_Bounds) {
2839e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
2849e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose        "Byte string function accesses out-of-bound array element"));
2859e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    }
2869e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get());
2879e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
2889e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    // Generate a report for this bug.
289e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    BugReport *report;
2909e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    if (warningMsg) {
291e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      report = new BugReport(*BT, warningMsg, N);
292e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    } else {
2939e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      assert(CurrentFunctionDescription);
2949e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      assert(CurrentFunctionDescription[0] != '\0');
2959e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
2969e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      llvm::SmallString<80> buf;
2979e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      llvm::raw_svector_ostream os(buf);
2989e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      os << (char)toupper(CurrentFunctionDescription[0])
2999e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose         << &CurrentFunctionDescription[1]
3009e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose         << " accesses out-of-bound array element";
301e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      report = new BugReport(*BT, os.str(), N);
302e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
303ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
304ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // FIXME: It would be nice to eventually make this diagnostic more clear,
305ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // e.g., by referencing the original declaration or by saying *why* this
306ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // reference is outside the range.
307ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
308ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    report->addRange(S->getSourceRange());
309ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    C.EmitReport(report);
310ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
311ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
312ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
313ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Array bound check succeeded.  From this point forward the array bound
314ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // should always succeed.
315ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return StInBound;
316ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
317ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
31818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
31918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                                 const ProgramState *state,
320ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                                 const Expr *Size,
321ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                                 const Expr *FirstBuf,
322e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                 const Expr *SecondBuf,
3239e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose                                                 const char *firstMessage,
3245e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose                                                 const char *secondMessage,
3255e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose                                                 bool WarnAboutSize) const {
326d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
327d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
328d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
329d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
330c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
3311e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose  ASTContext &Ctx = svalBuilder.getContext();
332ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
333c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
334ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
335ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
336a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  // Check that the first buffer is non-null.
337a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  SVal BufVal = state->getSVal(FirstBuf);
338c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, FirstBuf, BufVal);
339a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose  if (!state)
340a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    return NULL;
341a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
342d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // Get the access length and make sure it is known.
3439e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  // FIXME: This assumes the caller has already checked that the access length
3449e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  // is positive. And that it's unsigned.
345d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  SVal LengthVal = state->getSVal(Size);
346d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
347d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!Length)
348d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return state;
349d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
350ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Compute the offset of the last element to be accessed: size-1.
351c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
352c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
353c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                                    *Length, One, sizeTy));
354ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
355fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  // Check that the first buffer is sufficiently long.
356c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
357b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose  if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
3585e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    const Expr *warningExpr = (WarnAboutSize ? Size : FirstBuf);
3595e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose
360c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
361c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                          LastOffset, PtrTy);
3625e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    state = CheckLocation(C, state, warningExpr, BufEnd, firstMessage);
363ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
364b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    // If the buffer isn't large enough, abort.
365b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    if (!state)
366b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose      return NULL;
367b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose  }
368ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
369ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // If there's a second buffer, check it as well.
370ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (SecondBuf) {
371ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    BufVal = state->getSVal(SecondBuf);
372c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = checkNonNull(C, state, SecondBuf, BufVal);
373a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose    if (!state)
374a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose      return NULL;
375a6b808c6ba57723b997da2ef7a4a8cf48fbc2ba8Jordy Rose
376c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
377b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
3785e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose      const Expr *warningExpr = (WarnAboutSize ? Size : SecondBuf);
3795e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose
380c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
381c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                            LastOffset, PtrTy);
3825e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose      state = CheckLocation(C, state, warningExpr, BufEnd, secondMessage);
383b6a4026de13909c2b145166ae0b7d96cf1948f64Jordy Rose    }
384ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
385ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
386ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Large enough or not, return this state!
387ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return state;
388ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
389ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
39018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
39118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                            const ProgramState *state,
392d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                            const Expr *Size,
393ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                            const Expr *First,
394183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                            const Expr *Second) const {
395ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Do a simple check for overlap: if the two arguments are from the same
396ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // buffer, see if the end of the first is greater than the start of the second
397ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // or vice versa.
398ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
399d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If a previous check has failed, propagate the failure.
400d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  if (!state)
401d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    return NULL;
402d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
40318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *stateTrue, *stateFalse;
404ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
405ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the buffer values and make sure they're known locations.
406c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal firstVal = state->getSVal(First);
407c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal secondVal = state->getSVal(Second);
408ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
409c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  Loc *firstLoc = dyn_cast<Loc>(&firstVal);
410c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!firstLoc)
411ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
412ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
413c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  Loc *secondLoc = dyn_cast<Loc>(&secondVal);
414c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!secondLoc)
415ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
416ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
417ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Are the two values the same?
418c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
419c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateTrue, stateFalse) =
420c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
421ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
422ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue && !stateFalse) {
423ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // If the values are known to be equal, that's automatically an overlap.
424c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    emitOverlapBug(C, stateTrue, First, Second);
425ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
426ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
427ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
42828f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  // assume the two expressions are not equal.
429ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  assert(stateFalse);
430ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  state = stateFalse;
431ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
432ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Which value comes first?
433ee2fde12934c0b11a71db286d1dc9ee8341802a5Jordy Rose  QualType cmpTy = svalBuilder.getConditionType();
434c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
435c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                         *firstLoc, *secondLoc, cmpTy);
436c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
437c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (!reverseTest)
438ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
439ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
440c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
441ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue) {
442ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    if (stateFalse) {
443ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      // If we don't know which one comes first, we can't perform this test.
444ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      return state;
445ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    } else {
446c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      // Switch the values so that firstVal is before secondVal.
447c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      Loc *tmpLoc = firstLoc;
448c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      firstLoc = secondLoc;
449c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      secondLoc = tmpLoc;
450ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
451ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      // Switch the Exprs as well, so that they still correspond.
452ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      const Expr *tmpExpr = First;
453ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      First = Second;
454ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      Second = tmpExpr;
455ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    }
456ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
457ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
458ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the length, and make sure it too is known.
459ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  SVal LengthVal = state->getSVal(Size);
460ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
461ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!Length)
462ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
463ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
464ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Convert the first buffer's start address to char*.
465ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Bail out if the cast fails.
466ee2fde12934c0b11a71db286d1dc9ee8341802a5Jordy Rose  ASTContext &Ctx = svalBuilder.getContext();
467ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
4681e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose  SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy,
4691e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose                                         First->getType());
470ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
471ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FirstStartLoc)
472ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
473ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
474ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Compute the end of the first buffer. Bail out if THAT fails.
475c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
476ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose                                 *FirstStartLoc, *Length, CharPtrTy);
477ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
478ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FirstEndLoc)
479ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
480ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
481ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Is the end of the first buffer past the start of the second buffer?
482c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
483c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                *FirstEndLoc, *secondLoc, cmpTy);
484ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
485ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!OverlapTest)
486ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return state;
487ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
48828f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
489ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
490ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (stateTrue && !stateFalse) {
491ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    // Overlap!
492c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    emitOverlapBug(C, stateTrue, First, Second);
493ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return NULL;
494ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  }
495ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
49628f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek  // assume the two expressions don't overlap.
497ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  assert(stateFalse);
498ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return stateFalse;
499ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
500ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
50118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekvoid CStringChecker::emitOverlapBug(CheckerContext &C, const ProgramState *state,
502183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                  const Stmt *First, const Stmt *Second) const {
503d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  ExplodedNode *N = C.generateSink(state);
504ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!N)
505ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return;
506ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
507ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!BT_Overlap)
508183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    BT_Overlap.reset(new BugType("Unix API", "Improper arguments"));
509ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
510ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Generate a report for this bug.
511e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  BugReport *report =
512e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    new BugReport(*BT_Overlap,
513ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose      "Arguments must not be overlapping buffers", N);
514ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  report->addRange(First->getSourceRange());
515ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  report->addRange(Second->getSourceRange());
516ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
517ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  C.EmitReport(report);
518ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
519ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
52018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::checkAdditionOverflow(CheckerContext &C,
52118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                                     const ProgramState *state,
522d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                     NonLoc left,
523d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                     NonLoc right) const {
524d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // If a previous check has failed, propagate the failure.
525d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  if (!state)
526d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    return NULL;
527d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
528d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  SValBuilder &svalBuilder = C.getSValBuilder();
529d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
530d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
531d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  QualType sizeTy = svalBuilder.getContext().getSizeType();
532d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
533d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  NonLoc maxVal = svalBuilder.makeIntVal(maxValInt);
534d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
535d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  SVal maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right,
536d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                               sizeTy);
537d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
538d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  if (maxMinusRight.isUnknownOrUndef()) {
539d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // Try switching the operands. (The order of these two assignments is
540d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // important!)
541d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left,
542d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                            sizeTy);
543d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    left = right;
544d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  }
545d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
546d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  if (NonLoc *maxMinusRightNL = dyn_cast<NonLoc>(&maxMinusRight)) {
547d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    QualType cmpTy = svalBuilder.getConditionType();
548d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If left > max - right, we have an overflow.
549d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
550d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                *maxMinusRightNL, cmpTy);
551d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
55218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    const ProgramState *stateOverflow, *stateOkay;
553d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    llvm::tie(stateOverflow, stateOkay) =
554d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
555d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
556d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (stateOverflow && !stateOkay) {
557d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // We have an overflow. Emit a bug report.
558d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      ExplodedNode *N = C.generateSink(stateOverflow);
559d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (!N)
560d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        return NULL;
561d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
562d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (!BT_AdditionOverflow)
563d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        BT_AdditionOverflow.reset(new BuiltinBug("API",
564d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          "Sum of expressions causes overflow"));
565d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
566d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // This isn't a great error message, but this should never occur in real
567d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // code anyway -- you'd have to create a buffer longer than a size_t can
568d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // represent, which is sort of a contradiction.
5698cc2491239f0b9de35985a1650fffc05c1ca8242Jordy Rose      const char *warning =
5708cc2491239f0b9de35985a1650fffc05c1ca8242Jordy Rose        "This expression will create a string whose length is too big to "
5718cc2491239f0b9de35985a1650fffc05c1ca8242Jordy Rose        "be represented as a size_t";
572d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
573d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // Generate a report for this bug.
5748cc2491239f0b9de35985a1650fffc05c1ca8242Jordy Rose      BugReport *report = new BugReport(*BT_AdditionOverflow, warning, N);
575d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      C.EmitReport(report);
576d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
577d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      return NULL;
578d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    }
579d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
580d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // From now on, assume an overflow didn't occur.
581d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    assert(stateOkay);
582d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    state = stateOkay;
583d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  }
584d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
585d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  return state;
586d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose}
587d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
58818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::setCStringLength(const ProgramState *state,
589e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                const MemRegion *MR,
590c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                                SVal strLength) {
591c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  assert(!strLength.isUndef() && "Attempt to set an undefined string length");
592e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
593e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  MR = MR->StripCasts();
594e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
595e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  switch (MR->getKind()) {
596e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::StringRegionKind:
597e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: This can happen if we strcpy() into a string region. This is
598e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // undefined [C99 6.4.5p6], but we should still warn about it.
599e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
600e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
601e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::SymbolicRegionKind:
602e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::AllocaRegionKind:
603e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::VarRegionKind:
604e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::FieldRegionKind:
605e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::ObjCIvarRegionKind:
606210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose    // These are the types we can currently track string lengths for.
607210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose    break;
608e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
609e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  case MemRegion::ElementRegionKind:
610e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: Handle element regions by upper-bounding the parent region's
611e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // string length.
612e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
613e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
614e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  default:
615e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Other regions (mostly non-data) can't have a reliable C string length.
616e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // For now, just ignore the change.
617e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: These are rare but not impossible. We should output some kind of
618e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // warning for things like strcpy((char[]){'a', 0}, "b");
619e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
620e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
621210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose
622210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose  if (strLength.isUnknown())
623210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose    return state->remove<CStringLength>(MR);
624210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose
625210c05b10317a11971f87e474ffa4c30bb8e4df9Jordy Rose  return state->set<CStringLength>(MR, strLength);
626e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
627e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
628c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
62918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                               const ProgramState *&state,
630a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                               const Expr *Ex,
631d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                               const MemRegion *MR,
632d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                               bool hypothetical) {
633d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  if (!hypothetical) {
634d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If there's a recorded length, go ahead and return it.
635d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    const SVal *Recorded = state->get<CStringLength>(MR);
636d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (Recorded)
637d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      return *Recorded;
638d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  }
639a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
640a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Otherwise, get a new symbol and update the state.
6415d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks  unsigned Count = C.getCurrentBlockCount();
642c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
643c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = svalBuilder.getContext().getSizeType();
644183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
645183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                                    MR, Ex, sizeTy, Count);
646d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
647d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  if (!hypothetical)
648d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    state = state->set<CStringLength>(MR, strLength);
649d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
650c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return strLength;
651a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
652a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
65318c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekSVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&state,
654d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                      const Expr *Ex, SVal Buf,
655d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                      bool hypothetical) const {
65619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const MemRegion *MR = Buf.getAsRegion();
65719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  if (!MR) {
65819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // If we can't get a region, see if it's something we /know/ isn't a
65919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // C string. In the context of locations, the only time we can issue such
66019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    // a warning is for labels.
66119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
662d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek      if (ExplodedNode *N = C.generateNode(state)) {
66319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        if (!BT_NotCString)
664183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          BT_NotCString.reset(new BuiltinBug("API",
665183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis            "Argument is not a null-terminated string."));
66619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
66719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        llvm::SmallString<120> buf;
66819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        llvm::raw_svector_ostream os(buf);
6699e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose        assert(CurrentFunctionDescription);
6709e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose        os << "Argument to " << CurrentFunctionDescription
6719e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose           << " is the address of the label '" << Label->getLabel()->getName()
67219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose           << "', which is not a null-terminated string";
67319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
67419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        // Generate a report for this bug.
675e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        BugReport *report = new BugReport(*BT_NotCString,
67619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                                                          os.str(), N);
67719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
67819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        report->addRange(Ex->getSourceRange());
67919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose        C.EmitReport(report);
68019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      }
68119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
68219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      return UndefinedVal();
68319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
68419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
685a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // If it's not a region and not a label, give up.
686a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
687a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
68819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
689a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // If we have a region, strip casts from it and see if we can figure out
690a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // its length. For anything we can't figure out, just return UnknownVal.
691a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  MR = MR->StripCasts();
692a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
693a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  switch (MR->getKind()) {
694a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::StringRegionKind: {
695a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Modifying the contents of string regions is undefined [C99 6.4.5p6],
696a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // so we can assume that the byte length is the correct C string length.
697c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SValBuilder &svalBuilder = C.getSValBuilder();
698c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    QualType sizeTy = svalBuilder.getContext().getSizeType();
699c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
700c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
701a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
702a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::SymbolicRegionKind:
703a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::AllocaRegionKind:
704a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::VarRegionKind:
705a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::FieldRegionKind:
706a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::ObjCIvarRegionKind:
707d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    return getCStringLengthForRegion(C, state, Ex, MR, hypothetical);
708a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::CompoundLiteralRegionKind:
709a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: Can we track this? Is it necessary?
710a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
711a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  case MemRegion::ElementRegionKind:
712a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: How can we handle this? It's not good enough to subtract the
713a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // offset from the base string length; consider "123\x00567" and &a[5].
714a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UnknownVal();
715a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  default:
716a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Other regions (mostly non-data) can't have a reliable C string length.
717a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // In this case, an error is emitted and UndefinedVal is returned.
718a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // The caller should always be prepared to handle this case.
719d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    if (ExplodedNode *N = C.generateNode(state)) {
720a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (!BT_NotCString)
721183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis        BT_NotCString.reset(new BuiltinBug("API",
722183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          "Argument is not a null-terminated string."));
723a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
724a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      llvm::SmallString<120> buf;
725a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      llvm::raw_svector_ostream os(buf);
726a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
7279e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      assert(CurrentFunctionDescription);
7289e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      os << "Argument to " << CurrentFunctionDescription << " is ";
729a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
730a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (SummarizeRegion(os, C.getASTContext(), MR))
731a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        os << ", which is not a null-terminated string";
732a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      else
733a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        os << "not a null-terminated string";
734a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
735a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      // Generate a report for this bug.
736e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      BugReport *report = new BugReport(*BT_NotCString,
737a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose                                                        os.str(), N);
738a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
739a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      report->addRange(Ex->getSourceRange());
740a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      C.EmitReport(report);
74119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
74219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
743a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return UndefinedVal();
74419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
74519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
74619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
747318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maioraniconst StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
74818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *&state, const Expr *expr, SVal val) const {
749318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
750318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Get the memory region pointed to by the val.
751318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const MemRegion *bufRegion = val.getAsRegion();
752318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (!bufRegion)
753318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return NULL;
754318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
755318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Strip casts off the memory region.
756318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  bufRegion = bufRegion->StripCasts();
757318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
758318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Cast the memory region to a string region.
759318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
760318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (!strRegion)
761318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return NULL;
762318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
763318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Return the actual string in the string region.
764318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  return strRegion->getStringLiteral();
765318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani}
766318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
76718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *CStringChecker::InvalidateBuffer(CheckerContext &C,
76818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                                const ProgramState *state,
769e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose                                                const Expr *E, SVal V) {
770e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  Loc *L = dyn_cast<Loc>(&V);
771e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!L)
772e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return state;
773e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
774e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
775e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // some assumptions about the value that CFRefCount can't. Even so, it should
776e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // probably be refactored.
777e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
778e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    const MemRegion *R = MR->getRegion()->StripCasts();
779e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
780e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Are we dealing with an ElementRegion?  If so, we should be invalidating
781e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // the super-region.
782e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
783e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      R = ER->getSuperRegion();
784e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // FIXME: What about layers of ElementRegions?
785e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
786e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
787e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Invalidate this region.
7885d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks    unsigned Count = C.getCurrentBlockCount();
789537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose    return state->invalidateRegions(R, E, Count);
790e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
791e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
792e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If we have a non-region value by chance, just remove the binding.
793e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // FIXME: is this necessary or correct? This handles the non-Region
794e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  //  cases.  Is it ever valid to store to these?
795e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  return state->unbindLoc(*L);
796e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
797e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
7989c378f705405d37f49795d5e915989de774fe11fTed Kremenekbool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
79919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose                                     const MemRegion *MR) {
8009697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek  const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
80119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
802096aef9597b263b4cd6a0feaacf9e7214fa9c75aJordy Rose  switch (MR->getKind()) {
80319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::FunctionTextRegionKind: {
804096aef9597b263b4cd6a0feaacf9e7214fa9c75aJordy Rose    const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
80519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    if (FD)
806b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      os << "the address of the function '" << *FD << '\'';
80719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    else
80819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose      os << "the address of a function";
80919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
81019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
81119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::BlockTextRegionKind:
81219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    os << "block text";
81319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
81419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::BlockDataRegionKind:
81519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    os << "a block";
81619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
81719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::CXXThisRegionKind:
81802fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu  case MemRegion::CXXTempObjectRegionKind:
8199697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek    os << "a C++ temp object of type " << TVR->getValueType().getAsString();
82019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
82119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::VarRegionKind:
8229697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek    os << "a variable of type" << TVR->getValueType().getAsString();
82319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
82419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::FieldRegionKind:
8259697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek    os << "a field of type " << TVR->getValueType().getAsString();
82619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
82719c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  case MemRegion::ObjCIvarRegionKind:
8289697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek    os << "an instance variable of type " << TVR->getValueType().getAsString();
82919c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return true;
83019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  default:
83119c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    return false;
83219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
83319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
83419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
835d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
8369c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek// evaluation of individual function calls.
837d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
838ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
839b8b875be7b2d177d755641c6212111859372d611Lenny Maioranivoid CStringChecker::evalCopyCommon(CheckerContext &C,
840b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                                    const CallExpr *CE,
84118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    const ProgramState *state,
842d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose                                    const Expr *Size, const Expr *Dest,
843b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                                    const Expr *Source, bool Restricted,
844b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                                    bool IsMempcpy) const {
8459e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  CurrentFunctionDescription = "memory copy function";
8469e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
847d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // See if the size argument is zero.
848c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal sizeVal = state->getSVal(Size);
849c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
850d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
85118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *stateZeroSize, *stateNonZeroSize;
8521e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose  llvm::tie(stateZeroSize, stateNonZeroSize) =
8531e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose    assumeZero(C, state, sizeVal, sizeTy);
854d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
855b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  // Get the value of the Dest.
856b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  SVal destVal = state->getSVal(Dest);
857b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
858b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  // If the size is zero, there won't be any actual memory access, so
859b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  // just bind the return value to the destination buffer and return.
860b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  if (stateZeroSize) {
86122d27178bf795145439b9588e260ccceab79a088Jordy Rose    stateZeroSize = stateZeroSize->BindExpr(CE, destVal);
862c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    C.addTransition(stateZeroSize);
863b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  }
864d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
865d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be nonzero, we have to check the other arguments.
866c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateNonZeroSize) {
86722d27178bf795145439b9588e260ccceab79a088Jordy Rose    state = stateNonZeroSize;
868b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
869b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    // Ensure the destination is not null. If it is NULL there will be a
870b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    // NULL pointer dereference.
871b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    state = checkNonNull(C, state, Dest, destVal);
872b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    if (!state)
873b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani      return;
874b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
875b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    // Get the value of the Src.
876b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    SVal srcVal = state->getSVal(Source);
877b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
878b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    // Ensure the source is not null. If it is NULL there will be a
879b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    // NULL pointer dereference.
880b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    state = checkNonNull(C, state, Source, srcVal);
881b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani    if (!state)
882b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani      return;
883b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
8847182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // Ensure the accesses are valid and that the buffers do not overlap.
8859e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose    const char * const writeWarning =
8869e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose      "Memory copy function overflows destination buffer";
887e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    state = CheckBufferAccess(C, state, Size, Dest, Source,
8889e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose                              writeWarning, /* sourceWarning = */ NULL);
889d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (Restricted)
890d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckOverlap(C, state, Size, Dest, Source);
891e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
8927182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    if (!state)
8937182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      return;
8943f8bb2fa289c956a66613b0f09e3df5e25d27c66Jordy Rose
8957182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // If this is mempcpy, get the byte after the last byte copied and
8967182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // bind the expr.
8977182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    if (IsMempcpy) {
8987182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
8997182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      assert(destRegVal && "Destination should be a known MemRegionVal here");
9007182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose
9017182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      // Get the length to copy.
9027182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
9037182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose
9047182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      if (lenValNonLoc) {
9057182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        // Get the byte after the last byte copied.
9067182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
9077182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose                                                          *destRegVal,
9087182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose                                                          *lenValNonLoc,
9097182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose                                                          Dest->getType());
9107182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose
9117182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        // The byte after the last byte copied is the return value.
9127182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        state = state->BindExpr(CE, lastElement);
9133f8bb2fa289c956a66613b0f09e3df5e25d27c66Jordy Rose      } else {
9147182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        // If we don't know how much we copied, we can at least
9157182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        // conjure a return value for later.
9165d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks        unsigned Count = C.getCurrentBlockCount();
9177182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        SVal result =
9187182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose          C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
9197182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose        state = state->BindExpr(CE, result);
920b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani      }
921b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
9227182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    } else {
9237182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      // All other copies return the destination buffer.
9247182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      // (Well, bcopy() has a void return type, but this won't hurt.)
9257182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose      state = state->BindExpr(CE, destVal);
926e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
9277182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose
9287182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // Invalidate the destination.
9297182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // FIXME: Even if we can't perfectly model the copy, we should see if we
9307182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // can use LazyCompoundVals to copy the source values into the destination.
9317182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // This would probably remove any existing bindings past the end of the
9327182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    // copied region, but that's still an improvement over blank invalidation.
9337182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
9347182b9652f20c122d261d9255e11bf3a1bf871ecJordy Rose    C.addTransition(state);
935d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  }
936ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
937ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
938ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
939183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
940d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
941d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // The return value is the address of the destination buffer.
942d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const Expr *Dest = CE->getArg(0);
94318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
9443f8bb2fa289c956a66613b0f09e3df5e25d27c66Jordy Rose
945b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
946b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani}
947b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
948b8b875be7b2d177d755641c6212111859372d611Lenny Maioranivoid CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
949b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  // void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
950b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  // The return value is a pointer to the byte following the last written byte.
951b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  const Expr *Dest = CE->getArg(0);
95218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
953b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani
954b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
955d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
956ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
957183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
958d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void *memmove(void *dst, const void *src, size_t n);
959ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // The return value is the address of the destination buffer.
960d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  const Expr *Dest = CE->getArg(0);
96118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
9623f8bb2fa289c956a66613b0f09e3df5e25d27c66Jordy Rose
963b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
964ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
965ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
966183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
967d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // void bcopy(const void *src, void *dst, size_t n);
968b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani  evalCopyCommon(C, CE, C.getState(),
969b8b875be7b2d177d755641c6212111859372d611Lenny Maiorani                 CE->getArg(2), CE->getArg(1), CE->getArg(0));
970d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose}
971d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
972183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
973bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  // int memcmp(const void *s1, const void *s2, size_t n);
9749e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  CurrentFunctionDescription = "memory comparison function";
9759e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
976bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Left = CE->getArg(0);
977bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Right = CE->getArg(1);
978bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  const Expr *Size = CE->getArg(2);
979bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
98018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
981c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SValBuilder &svalBuilder = C.getSValBuilder();
982bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
983d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // See if the size argument is zero.
984c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal sizeVal = state->getSVal(Size);
985c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  QualType sizeTy = Size->getType();
986bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
98718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *stateZeroSize, *stateNonZeroSize;
988c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  llvm::tie(stateZeroSize, stateNonZeroSize) =
989c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    assumeZero(C, state, sizeVal, sizeTy);
990bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
991d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be zero, the result will be 0 in that case, and we don't
992d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // have to check either of the buffers.
993c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateZeroSize) {
994c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = stateZeroSize;
995c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
996d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    C.addTransition(state);
997bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose  }
998bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
999d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the size can be nonzero, we have to check the other arguments.
1000c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (stateNonZeroSize) {
1001c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = stateNonZeroSize;
1002d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // If we know the two buffers are the same, we know the result is 0.
1003d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // First, get the two buffers' addresses. Another checker will have already
1004d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // made sure they're not undefined.
1005d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
1006d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
1007d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
1008d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // See if they are the same.
1009c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
101018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    const ProgramState *StSameBuf, *StNotSameBuf;
101128f47b92e760ccf641ac91cb0fe1c12d9ca89795Ted Kremenek    llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
1012d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose
10131e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose    // If the two arguments might be the same buffer, we know the result is 0,
1014d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // and we only need to check one size.
1015d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (StSameBuf) {
1016d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = StSameBuf;
1017d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckBufferAccess(C, state, Size, Left);
1018d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      if (state) {
1019c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
1020d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        C.addTransition(state);
1021d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      }
1022d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    }
1023bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
1024d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // If the two arguments might be different buffers, we have to check the
1025d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    // size of both of them.
1026d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    if (StNotSameBuf) {
1027d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = StNotSameBuf;
1028d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      state = CheckBufferAccess(C, state, Size, Left, Right);
1029d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      if (state) {
1030d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        // The return value is the comparison result, which we don't know.
10315d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks        unsigned Count = C.getCurrentBlockCount();
1032c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
1033d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        state = state->BindExpr(CE, CmpV);
1034d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose        C.addTransition(state);
1035d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose      }
1036d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose    }
1037d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  }
1038bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose}
1039bc56d1f6e2288aea9546b2380c71288939d688caJordy Rose
1040183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalstrLength(CheckerContext &C,
1041183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                   const CallExpr *CE) const {
104219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  // size_t strlen(const char *s);
1043be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
1044be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek}
1045be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
1046183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalstrnLength(CheckerContext &C,
1047183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                    const CallExpr *CE) const {
1048be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  // size_t strnlen(const char *s, size_t maxlen);
1049be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek  evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
1050be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek}
1051be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
1052be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenekvoid CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
1053183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                         bool IsStrnlen) const {
10549e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  CurrentFunctionDescription = "string length function";
105518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1056793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1057793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose  if (IsStrnlen) {
1058793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    const Expr *maxlenExpr = CE->getArg(1);
1059793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    SVal maxlenVal = state->getSVal(maxlenExpr);
1060793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
106118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    const ProgramState *stateZeroSize, *stateNonZeroSize;
1062793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    llvm::tie(stateZeroSize, stateNonZeroSize) =
1063793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      assumeZero(C, state, maxlenVal, maxlenExpr->getType());
1064793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1065793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    // If the size can be zero, the result will be 0 in that case, and we don't
1066793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    // have to check the string itself.
1067793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    if (stateZeroSize) {
1068793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      SVal zero = C.getSValBuilder().makeZeroVal(CE->getType());
1069793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      stateZeroSize = stateZeroSize->BindExpr(CE, zero);
1070793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      C.addTransition(stateZeroSize);
1071793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    }
1072793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1073793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    // If the size is GUARANTEED to be zero, we're done!
1074793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    if (!stateNonZeroSize)
1075793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      return;
1076793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1077793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    // Otherwise, record the assumption that the size is nonzero.
1078793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose    state = stateNonZeroSize;
1079793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose  }
1080793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1081793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose  // Check that the string argument is non-null.
108219c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  const Expr *Arg = CE->getArg(0);
108319c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  SVal ArgVal = state->getSVal(Arg);
108419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
1085c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, Arg, ArgVal);
108619c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
1087bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  if (!state)
1088bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    return;
1089a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1090bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  SVal strLength = getCStringLength(C, state, Arg, ArgVal);
1091a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1092bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  // If the argument isn't a valid C string, there's no valid state to
1093bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  // transition to.
1094bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  if (strLength.isUndef())
1095bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    return;
1096be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek
1097bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  DefinedOrUnknownSVal result = UnknownVal();
1098793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1099bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  // If the check is for strnlen() then bind the return value to no more than
1100bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  // the maxlen value.
1101bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  if (IsStrnlen) {
1102ee2fde12934c0b11a71db286d1dc9ee8341802a5Jordy Rose    QualType cmpTy = C.getSValBuilder().getConditionType();
1103793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose
1104bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    // It's a little unfortunate to be getting this again,
1105bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    // but it's not that expensive...
1106bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    const Expr *maxlenExpr = CE->getArg(1);
1107bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    SVal maxlenVal = state->getSVal(maxlenExpr);
1108bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1109bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
1110bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
1111bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1112bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    if (strLengthNL && maxlenValNL) {
111318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek      const ProgramState *stateStringTooLong, *stateStringNotTooLong;
1114bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1115bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      // Check if the strLength is greater than the maxlen.
1116bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      llvm::tie(stateStringTooLong, stateStringNotTooLong) =
1117bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        state->assume(cast<DefinedOrUnknownSVal>
1118bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                      (C.getSValBuilder().evalBinOpNN(state, BO_GT,
1119bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                      *strLengthNL,
1120bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                      *maxlenValNL,
1121bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                      cmpTy)));
1122bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1123bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      if (stateStringTooLong && !stateStringNotTooLong) {
1124bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        // If the string is longer than maxlen, return maxlen.
1125bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        result = *maxlenValNL;
1126bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      } else if (stateStringNotTooLong && !stateStringTooLong) {
1127bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        // If the string is shorter than maxlen, return its length.
1128bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        result = *strLengthNL;
1129793bff3fb7ca2a31e81aa7f4f3f21f921459010bJordy Rose      }
113019c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose    }
1131a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1132bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    if (result.isUnknown()) {
1133bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      // If we don't have enough information for a comparison, there's
1134bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      // no guarantee the full string length will actually be returned.
1135bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      // All we know is the return value is the min of the string length
1136bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      // and the limit. This is better than nothing.
11375d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks      unsigned Count = C.getCurrentBlockCount();
1138bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
1139bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      NonLoc *resultNL = cast<NonLoc>(&result);
1140bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1141bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      if (strLengthNL) {
1142bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        state = state->assume(cast<DefinedOrUnknownSVal>
1143bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                              (C.getSValBuilder().evalBinOpNN(state, BO_LE,
1144bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              *resultNL,
1145bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              *strLengthNL,
1146bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              cmpTy)), true);
1147bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      }
1148bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1149bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      if (maxlenValNL) {
1150bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose        state = state->assume(cast<DefinedOrUnknownSVal>
1151bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                              (C.getSValBuilder().evalBinOpNN(state, BO_LE,
1152bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              *resultNL,
1153bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              *maxlenValNL,
1154bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose                                                              cmpTy)), true);
1155bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      }
1156bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    }
1157bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1158bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  } else {
1159bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    // This is a plain strlen(), not strnlen().
1160bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    result = cast<DefinedOrUnknownSVal>(strLength);
1161bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1162bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    // If we don't know the length of the string, conjure a return
1163bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    // value, so it can be used in constraints, at least.
1164bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    if (result.isUnknown()) {
11655d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks      unsigned Count = C.getCurrentBlockCount();
1166bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
1167bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose    }
116819c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose  }
1169bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose
1170bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  // Bind the return value.
1171bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  assert(!result.isUnknown() && "Should have conjured a value by now");
1172bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  state = state->BindExpr(CE, result);
1173bd32beee8a0f22e1d5245112f5e34ad4669994aeJordy Rose  C.addTransition(state);
117419c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose}
117519c5dd120e42b1ba0642309a185c70f4a41aadbdJordy Rose
1176183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
1177e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // char *strcpy(char *restrict dst, const char *restrict src);
1178067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  evalStrcpyCommon(C, CE,
1179067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* returnEnd = */ false,
1180067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isBounded = */ false,
1181067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isAppending = */ false);
11820ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek}
11830ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
1184183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
1185c152586baf0fcdfd4c660e5dcd7b6857f13203d6Jordy Rose  // char *strncpy(char *restrict dst, const char *restrict src, size_t n);
1186067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  evalStrcpyCommon(C, CE,
1187067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* returnEnd = */ false,
1188067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isBounded = */ true,
1189067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isAppending = */ false);
1190e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
1191e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1192183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
1193e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // char *stpcpy(char *restrict dst, const char *restrict src);
1194067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  evalStrcpyCommon(C, CE,
1195067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* returnEnd = */ true,
1196067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isBounded = */ false,
1197067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isAppending = */ false);
1198067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani}
1199067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1200067bbd0e11c71a33b51832532e836971be697699Lenny Maioranivoid CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
1201067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  //char *strcat(char *restrict s1, const char *restrict s2);
1202067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  evalStrcpyCommon(C, CE,
1203067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* returnEnd = */ false,
1204067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isBounded = */ false,
1205067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isAppending = */ true);
1206067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani}
1207067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1208067bbd0e11c71a33b51832532e836971be697699Lenny Maioranivoid CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
1209067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  //char *strncat(char *restrict s1, const char *restrict s2, size_t n);
1210067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  evalStrcpyCommon(C, CE,
1211067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* returnEnd = */ false,
1212067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isBounded = */ true,
1213067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                   /* isAppending = */ true);
1214e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
1215e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
12169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenekvoid CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
1217067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                                      bool returnEnd, bool isBounded,
1218067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani                                      bool isAppending) const {
12199e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  CurrentFunctionDescription = "string copy function";
122018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1221e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1222067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  // Check that the destination is non-null.
1223e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  const Expr *Dst = CE->getArg(0);
1224e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  SVal DstVal = state->getSVal(Dst);
1225e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1226c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, Dst, DstVal);
1227e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!state)
1228e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
1229e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1230e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Check that the source is non-null.
1231c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const Expr *srcExpr = CE->getArg(1);
1232c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal srcVal = state->getSVal(srcExpr);
1233c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  state = checkNonNull(C, state, srcExpr, srcVal);
1234e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  if (!state)
1235e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
1236e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1237e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Get the string length of the source.
1238c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal strLength = getCStringLength(C, state, srcExpr, srcVal);
1239e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1240e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If the source isn't a valid C string, give up.
1241c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (strLength.isUndef())
1242e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    return;
1243e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1244d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  SValBuilder &svalBuilder = C.getSValBuilder();
1245d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  QualType cmpTy = svalBuilder.getConditionType();
12468912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  QualType sizeTy = svalBuilder.getContext().getSizeType();
1247d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
12488912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  // These two values allow checking two kinds of errors:
12498912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  // - actual overflows caused by a source that doesn't fit in the destination
12508912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  // - potential overflows caused by a bound that could exceed the destination
1251d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  SVal amountCopied = UnknownVal();
12528912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  SVal maxLastElementIndex = UnknownVal();
12538912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose  const char *boundWarning = NULL;
1254d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1255067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  // If the function is strncpy, strncat, etc... it is bounded.
1256067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  if (isBounded) {
1257067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    // Get the max number of characters to copy.
12580ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    const Expr *lenExpr = CE->getArg(2);
12590ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    SVal lenVal = state->getSVal(lenExpr);
12600ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
1261d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // Protect against misdeclared strncpy().
12628912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType());
1263508c627db67ea4b53439fbcd688145f24d9c0400Lenny Maiorani
1264d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
12650ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek    NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
12660ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
1267d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If we know both values, we might be able to figure out how much
1268d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // we're copying.
1269d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (strLengthNL && lenValNL) {
127018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek      const ProgramState *stateSourceTooLong, *stateSourceNotTooLong;
1271d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1272d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // Check if the max number to copy is less than the length of the src.
12738912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // If the bound is equal to the source length, strncpy won't null-
12748912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // terminate the result!
1275d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      llvm::tie(stateSourceTooLong, stateSourceNotTooLong) =
1276d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        state->assume(cast<DefinedOrUnknownSVal>
12778912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                      (svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL,
1278d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                               *lenValNL, cmpTy)));
1279d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1280d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (stateSourceTooLong && !stateSourceNotTooLong) {
1281d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        // Max number to copy is less than the length of the src, so the actual
1282d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        // strLength copied is the max number arg.
1283d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        state = stateSourceTooLong;
1284d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        amountCopied = lenVal;
1285d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1286d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      } else if (!stateSourceTooLong && stateSourceNotTooLong) {
1287d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        // The source buffer entirely fits in the bound.
1288d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        state = stateSourceNotTooLong;
1289d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        amountCopied = strLength;
1290d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      }
1291d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    }
1292d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
12935e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    // We still want to know if the bound is known to be too large.
12948912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    if (lenValNL) {
12958912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      if (isAppending) {
12968912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // For strncat, the check is strlen(dst) + lenVal < sizeof(dst)
12978912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
12988912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // Get the string length of the destination. If the destination is
12998912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // memory that can't have a string length, we shouldn't be copying
13008912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // into it anyway.
13018912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
13028912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        if (dstStrLength.isUndef())
13038912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          return;
13048912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
13058912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        if (NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength)) {
13068912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Add,
13078912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                        *lenValNL,
13088912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                        *dstStrLengthNL,
13098912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                        sizeTy);
13108912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          boundWarning = "Size argument is greater than the free space in the "
13118912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                         "destination buffer";
13128912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        }
13138912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
13148912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      } else {
13158912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // For strncpy, this is just checking that lenVal <= sizeof(dst)
13168912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // (Yes, strncpy and strncat differ in how they treat termination.
13178912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        // strncat ALWAYS terminates, but strncpy doesn't.)
13188912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        NonLoc one = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
13198912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL,
13208912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                      one, sizeTy);
13218912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        boundWarning = "Size argument is greater than the length of the "
13228912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                       "destination buffer";
13238912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      }
13248912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    }
13255e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose
1326d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If we couldn't pin down the copy length, at least bound it.
13278912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // FIXME: We should actually run this code path for append as well, but
13288912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // right now it creates problems with constraints (since we can end up
13298912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // trying to pass constraints from symbol to symbol).
13308912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    if (amountCopied.isUnknown() && !isAppending) {
1331d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // Try to get a "hypothetical" string length symbol, which we can later
1332d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // set as a real value if that turns out to be the case.
1333d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      amountCopied = getCStringLength(C, state, lenExpr, srcVal, true);
1334d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      assert(!amountCopied.isUndef());
1335d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1336d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (NonLoc *amountCopiedNL = dyn_cast<NonLoc>(&amountCopied)) {
1337d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        if (lenValNL) {
1338d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          // amountCopied <= lenVal
1339d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          SVal copiedLessThanBound = svalBuilder.evalBinOpNN(state, BO_LE,
1340d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                             *amountCopiedNL,
1341d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                             *lenValNL,
1342d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                             cmpTy);
1343d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanBound),
1344d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                true);
1345d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          if (!state)
1346d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose            return;
1347d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        }
1348d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1349d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        if (strLengthNL) {
1350d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          // amountCopied <= strlen(source)
1351d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          SVal copiedLessThanSrc = svalBuilder.evalBinOpNN(state, BO_LE,
1352d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                           *amountCopiedNL,
1353d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                           *strLengthNL,
1354d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                           cmpTy);
1355d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
1356d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                true);
1357d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          if (!state)
1358d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose            return;
1359d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        }
1360d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      }
1361d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    }
1362d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1363d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  } else {
1364d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // The function isn't bounded. The amount copied should match the length
1365d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // of the source buffer.
1366d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    amountCopied = strLength;
13670ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek  }
13680ef473f75426f0a95635d0a9dd567d27b07dbd5bTed Kremenek
1369d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  assert(state);
1370d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1371d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // This represents the number of characters copied into the destination
1372d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // buffer. (It may not actually be the strlen if the destination buffer
1373d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // is not terminated.)
1374d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  SVal finalStrLength = UnknownVal();
1375d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1376067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  // If this is an appending function (strcat, strncat...) then set the
1377067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  // string length to strlen(src) + strlen(dst) since the buffer will
1378067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  // ultimately contain both.
1379067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  if (isAppending) {
13801e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose    // Get the string length of the destination. If the destination is memory
13811e022415b9a66c84a9005b4e0bb2d4becb76d189Jordy Rose    // that can't have a string length, we shouldn't be copying into it anyway.
1382067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
1383067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    if (dstStrLength.isUndef())
1384067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani      return;
1385067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1386d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&amountCopied);
1387067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
1388067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1389d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If we know both string lengths, we might know the final string length.
1390d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (srcStrLengthNL && dstStrLengthNL) {
1391d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // Make sure the two lengths together don't overflow a size_t.
1392d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      state = checkAdditionOverflow(C, state, *srcStrLengthNL, *dstStrLengthNL);
1393d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (!state)
1394d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        return;
1395d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1396d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *srcStrLengthNL,
1397d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                               *dstStrLengthNL, sizeTy);
1398d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    }
1399067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1400d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // If we couldn't get a single value for the final string length,
1401d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // we can at least bound it by the individual lengths.
1402d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (finalStrLength.isUnknown()) {
1403d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // Try to get a "hypothetical" string length symbol, which we can later
1404d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      // set as a real value if that turns out to be the case.
1405d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      finalStrLength = getCStringLength(C, state, CE, DstVal, true);
1406d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      assert(!finalStrLength.isUndef());
1407d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1408d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      if (NonLoc *finalStrLengthNL = dyn_cast<NonLoc>(&finalStrLength)) {
1409d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        if (srcStrLengthNL) {
1410d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          // finalStrLength >= srcStrLength
1411d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          SVal sourceInResult = svalBuilder.evalBinOpNN(state, BO_GE,
1412d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                        *finalStrLengthNL,
1413d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                        *srcStrLengthNL,
1414d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                        cmpTy);
1415d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          state = state->assume(cast<DefinedOrUnknownSVal>(sourceInResult),
1416d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                true);
1417d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          if (!state)
1418d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose            return;
1419d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        }
1420d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1421d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        if (dstStrLengthNL) {
1422d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          // finalStrLength >= dstStrLength
1423d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE,
1424d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                      *finalStrLengthNL,
1425d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                      *dstStrLengthNL,
1426d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                                      cmpTy);
1427d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
1428d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose                                true);
1429d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose          if (!state)
1430d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose            return;
1431d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose        }
1432d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      }
1433d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    }
1434067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1435d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  } else {
1436d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and
1437d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    // the final string length will match the input string length.
1438d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    finalStrLength = amountCopied;
1439067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani  }
1440067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani
1441d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // The final result of the function will either be a pointer past the last
1442d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  // copied element, or a pointer to the start of the destination buffer.
1443c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  SVal Result = (returnEnd ? UnknownVal() : DstVal);
1444e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1445d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  assert(state);
1446d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1447e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If the destination is a MemRegion, try to check for a buffer overflow and
1448e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // record the new string length.
1449c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
14508912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    QualType ptrTy = Dst->getType();
14518912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
14528912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // If we have an exact value on a bounded copy, use that to check for
14538912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // overflows, rather than our estimate about how much is actually copied.
14548912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    if (boundWarning) {
14558912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      if (NonLoc *maxLastNL = dyn_cast<NonLoc>(&maxLastElementIndex)) {
14568912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
14578912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                      *maxLastNL, ptrTy);
14588912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        state = CheckLocation(C, state, CE->getArg(2), maxLastElement,
14598912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                              boundWarning);
14608912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        if (!state)
14618912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          return;
14628912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      }
14638912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    }
14648912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
14658912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    // Then, if the final length is known...
1466d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&finalStrLength)) {
1467d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
14688912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose                                                 *knownStrLength, ptrTy);
14698912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose
14708912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // ...and we haven't checked the bound, we'll check the actual copy.
14718912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      if (!boundWarning) {
14728912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        const char * const warningMsg =
14738912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          "String copy function overflows destination buffer";
14748912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        state = CheckLocation(C, state, Dst, lastElement, warningMsg);
14758912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        if (!state)
14768912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose          return;
14778912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      }
1478e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1479e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose      // If this is a stpcpy-style copy, the last element is the return value.
1480c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      if (returnEnd)
1481c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        Result = lastElement;
1482e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    }
1483e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1484e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // Invalidate the destination. This must happen before we set the C string
1485e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // length because invalidation will clear the length.
1486e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // FIXME: Even if we can't perfectly model the copy, we should see if we
1487e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // can use LazyCompoundVals to copy the source values into the destination.
1488e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // This would probably remove any existing bindings past the end of the
1489e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose    // string, but that's still an improvement over blank invalidation.
1490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = InvalidateBuffer(C, state, Dst, *dstRegVal);
1491e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
14925e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    // Set the C string length of the destination, if we know it.
14938912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    if (isBounded && !isAppending) {
14948912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // strncpy is annoying in that it doesn't guarantee to null-terminate
14958912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // the result string. If the original string didn't fit entirely inside
14968912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // the bound (including the null-terminator), we don't know how long the
14978912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      // result is.
14988912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose      if (amountCopied != strLength)
14998912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose        finalStrLength = UnknownVal();
15008912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    }
15018912aaedb413b15f6dd1d8997d80e1d505f7d52fJordy Rose    state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength);
1502e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
1503e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1504d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose  assert(state);
1505d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1506e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // If this is a stpcpy-style copy, but we were unable to check for a buffer
1507e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // overflow, we still need a result. Conjure a return value.
1508c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  if (returnEnd && Result.isUnknown()) {
15095d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks    unsigned Count = C.getCurrentBlockCount();
1510d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    Result = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
1511e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  }
1512e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1513e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  // Set the return value.
1514e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  state = state->BindExpr(CE, Result);
1515e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose  C.addTransition(state);
1516e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose}
1517e64f311c11a8751867c2538807054f4817c1f5cbJordy Rose
1518318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maioranivoid CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
1519adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  //int strcmp(const char *s1, const char *s2);
1520bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani  evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
1521357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani}
1522357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani
1523357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maioranivoid CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
1524adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  //int strncmp(const char *s1, const char *s2, size_t n);
1525bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani  evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
1526bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani}
1527bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani
1528bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maioranivoid CStringChecker::evalStrcasecmp(CheckerContext &C,
1529bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani                                    const CallExpr *CE) const {
1530adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  //int strcasecmp(const char *s1, const char *s2);
1531bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani  evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
1532357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani}
1533318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1534454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maioranivoid CStringChecker::evalStrncasecmp(CheckerContext &C,
1535454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani                                     const CallExpr *CE) const {
1536adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  //int strncasecmp(const char *s1, const char *s2, size_t n);
1537454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani  evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true);
1538454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani}
1539454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani
1540357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maioranivoid CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
1541bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani                                      bool isBounded, bool ignoreCase) const {
15429e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  CurrentFunctionDescription = "string comparison function";
154318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1544318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1545318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Check that the first string is non-null
1546318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const Expr *s1 = CE->getArg(0);
1547318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  SVal s1Val = state->getSVal(s1);
1548318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  state = checkNonNull(C, state, s1, s1Val);
1549318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (!state)
1550318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return;
1551318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1552318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Check that the second string is non-null.
1553318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const Expr *s2 = CE->getArg(1);
1554318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  SVal s2Val = state->getSVal(s2);
1555318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  state = checkNonNull(C, state, s2, s2Val);
1556318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (!state)
1557318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return;
1558318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1559318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Get the string length of the first string or give up.
1560318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  SVal s1Length = getCStringLength(C, state, s1, s1Val);
1561318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (s1Length.isUndef())
1562318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return;
1563318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1564318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  // Get the string length of the second string or give up.
1565318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  SVal s2Length = getCStringLength(C, state, s2, s2Val);
1566318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  if (s2Length.isUndef())
1567318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    return;
1568318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1569adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // If we know the two buffers are the same, we know the result is 0.
1570adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // First, get the two buffers' addresses. Another checker will have already
1571adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // made sure they're not undefined.
1572adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(s1Val);
1573adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(s2Val);
1574adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1575adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // See if they are the same.
1576adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  SValBuilder &svalBuilder = C.getSValBuilder();
1577adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
157818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *StSameBuf, *StNotSameBuf;
1579adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
1580adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1581adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // If the two arguments might be the same buffer, we know the result is 0,
1582adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // and we only need to check one size.
1583adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  if (StSameBuf) {
1584adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    StSameBuf = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
1585adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    C.addTransition(StSameBuf);
1586adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1587adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    // If the two arguments are GUARANTEED to be the same, we're done!
1588adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    if (!StNotSameBuf)
1589adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      return;
1590adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  }
1591adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1592adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  assert(StNotSameBuf);
1593adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  state = StNotSameBuf;
1594318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1595adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // At this point we can go about comparing the two buffers.
1596adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // For now, we only do this if they're both known string literals.
1597adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1598adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // Attempt to extract string literals from both expressions.
1599adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  const StringLiteral *s1StrLiteral = getCStringLiteral(C, state, s1, s1Val);
1600318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  const StringLiteral *s2StrLiteral = getCStringLiteral(C, state, s2, s2Val);
1601adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  bool canComputeResult = false;
1602adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1603adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  if (s1StrLiteral && s2StrLiteral) {
16045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef s1StrRef = s1StrLiteral->getString();
16055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef s2StrRef = s2StrLiteral->getString();
1606adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1607adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    if (isBounded) {
1608adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // Get the max number of characters to compare.
1609adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      const Expr *lenExpr = CE->getArg(2);
1610adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      SVal lenVal = state->getSVal(lenExpr);
1611adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1612adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // If the length is known, we can get the right substrings.
1613adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) {
1614adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        // Create substrings of each to compare the prefix.
1615adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        s1StrRef = s1StrRef.substr(0, (size_t)len->getZExtValue());
1616adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        s2StrRef = s2StrRef.substr(0, (size_t)len->getZExtValue());
1617adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        canComputeResult = true;
1618adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      }
1619adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    } else {
1620adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // This is a normal, unbounded strcmp.
1621adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      canComputeResult = true;
1622adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    }
1623318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1624adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    if (canComputeResult) {
1625adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // Real strcmp stops at null characters.
1626adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      size_t s1Term = s1StrRef.find('\0');
16275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      if (s1Term != StringRef::npos)
1628adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        s1StrRef = s1StrRef.substr(0, s1Term);
1629357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani
1630adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      size_t s2Term = s2StrRef.find('\0');
16315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      if (s2Term != StringRef::npos)
1632adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        s2StrRef = s2StrRef.substr(0, s2Term);
1633adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1634adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // Use StringRef's comparison methods to compute the actual result.
1635adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      int result;
1636adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose
1637adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      if (ignoreCase) {
1638adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        // Compare string 1 to string 2 the same way strcasecmp() does.
1639adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        result = s1StrRef.compare_lower(s2StrRef);
1640adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      } else {
1641adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        // Compare string 1 to string 2 the same way strcmp() does.
1642adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose        result = s1StrRef.compare(s2StrRef);
1643adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      }
1644357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani
1645adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      // Build the SVal of the comparison and bind the return value.
1646adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      SVal resultVal = svalBuilder.makeIntVal(result, CE->getType());
1647adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose      state = state->BindExpr(CE, resultVal);
1648adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    }
1649454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani  }
1650bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani
1651adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  if (!canComputeResult) {
1652adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    // Conjure a symbolic value. It's the best we can do.
16535d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks    unsigned Count = C.getCurrentBlockCount();
1654adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
1655adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose    state = state->BindExpr(CE, resultVal);
1656357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani  }
1657318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1658adc42d412d747391dbcee234610f00b0f087cf7bJordy Rose  // Record this as a possible path.
1659318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani  C.addTransition(state);
1660318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani}
1661318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani
1662d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
1663a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose// The driver method, and other Checker callbacks.
1664d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose//===----------------------------------------------------------------------===//
1665ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
1666183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisbool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
1667ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the callee.  All the functions we care about are C functions
1668ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // with simple identifiers.
166918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1670ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const Expr *Callee = CE->getCallee();
1671ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
1672ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
1673ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (!FD)
1674ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return false;
1675ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
1676ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  // Get the name of the callee. If it's a builtin, strip off the prefix.
167790d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor  IdentifierInfo *II = FD->getIdentifier();
167890d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor  if (!II)   // if no identifier, not a simple C function
167990d26a4afdbf6d917a5241ef3b316e1c8337c9b8Douglas Gregor    return false;
16805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Name = II->getName();
1681ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  if (Name.startswith("__builtin_"))
1682ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    Name = Name.substr(10);
1683ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
16849c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
16859c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
1686be460d8e5364c6bffeb7b27e4c0d4d5d16e39c59Jordy Rose    .Cases("mempcpy", "__mempcpy_chk", &CStringChecker::evalMempcpy)
16879c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
16889c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
16899c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
16905e5f15062bcf4b62fda9062b453178f8b9bd0c2dJordy Rose    .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
16919c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
1692067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat)
1693067bbd0e11c71a33b51832532e836971be697699Lenny Maiorani    .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat)
1694c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    .Case("strlen", &CStringChecker::evalstrLength)
1695be4242ce039f0542ea0dd5f234aa0ee698f90c53Ted Kremenek    .Case("strnlen", &CStringChecker::evalstrnLength)
1696318dd92ad834857ea5bb91de288c1eb56cdbec1aLenny Maiorani    .Case("strcmp", &CStringChecker::evalStrcmp)
1697357f6ee9f1f6f8e5027377cb3e5907c62c4fe3dfLenny Maiorani    .Case("strncmp", &CStringChecker::evalStrncmp)
1698bd1d16a1792cd6ea5ede9869e18d781e3fc1a8c3Lenny Maiorani    .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
1699454fd2d3a1b6d0ef225c5d3927c1ad3b97510d1aLenny Maiorani    .Case("strncasecmp", &CStringChecker::evalStrncasecmp)
17009c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    .Case("bcopy", &CStringChecker::evalBcopy)
1701ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    .Default(NULL);
1702ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
1703d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // If the callee isn't a string function, let another checker handle it.
17049c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  if (!evalFunction)
1705ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose    return false;
1706ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose
17079e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  // Make sure each function sets its own description.
17089e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  // (But don't bother in a release build.)
17099e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose  assert(!(CurrentFunctionDescription = NULL));
17109e49d9fbdc861c25c2480233147dee07f5fa9660Jordy Rose
1711d325ffb9cbd26b6a3f219d115191d9a00b6dea8cJordy Rose  // Check and evaluate the call.
17129c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  (this->*evalFunction)(C, CE);
1713ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose  return true;
1714ccbf7eebc8425429e8fd9f9124770f86a74864ebJordy Rose}
1715a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1716183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
1717a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Record string length for char a[] = "abc";
171818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1719a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1720a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
1721a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1722a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const VarDecl *D = dyn_cast<VarDecl>(*I);
1723a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!D)
1724a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1725a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1726a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // FIXME: Handle array fields of structs.
1727a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!D->getType()->isArrayType())
1728a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1729a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1730a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const Expr *Init = D->getInit();
1731a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!Init)
1732a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1733a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!isa<StringLiteral>(Init))
1734a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1735a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1736a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
1737a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *MR = VarLoc.getAsRegion();
1738a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (!MR)
1739a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1740a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1741a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal StrVal = state->getSVal(Init);
1742a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    assert(StrVal.isValid() && "Initializer string is unknown or undefined");
1743c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    DefinedOrUnknownSVal strLength
1744c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
1745a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1746c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    state = state->set<CStringLength>(MR, strLength);
1747a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1748a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1749a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  C.addTransition(state);
1750a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1751a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
175218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekbool CStringChecker::wantsRegionChangeUpdate(const ProgramState *state) const {
1753a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1754a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  return !Entries.isEmpty();
1755a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1756a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
175718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *
175818c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCStringChecker::checkRegionChanges(const ProgramState *state,
175935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                                   const StoreManager::InvalidatedSymbols *,
1760537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                   ArrayRef<const MemRegion *> ExplicitRegions,
1761537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                   ArrayRef<const MemRegion *> Regions) const {
1762a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1763a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (Entries.isEmpty())
1764a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return state;
1765a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1766a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
1767a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
1768a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1769a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // First build sets for the changed regions and their super-regions.
1770537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  for (ArrayRef<const MemRegion *>::iterator
1771537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose       I = Regions.begin(), E = Regions.end(); I != E; ++I) {
1772537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose    const MemRegion *MR = *I;
1773a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    Invalidated.insert(MR);
1774a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1775a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SuperRegions.insert(MR);
1776a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
1777a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      MR = SR->getSuperRegion();
1778a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      SuperRegions.insert(MR);
1779a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1780a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1781a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1782a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1783a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1784a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Then loop over the entries in the current state.
1785a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(),
1786a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       E = Entries.end(); I != E; ++I) {
1787a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *MR = I.getKey();
1788a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1789a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Is this entry for a super-region of a changed region?
1790a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (SuperRegions.count(MR)) {
17913baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      Entries = F.remove(Entries, MR);
1792a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      continue;
1793a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1794a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1795a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    // Is this entry for a sub-region of a changed region?
1796a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    const MemRegion *Super = MR;
1797a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
1798a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      Super = SR->getSuperRegion();
1799a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (Invalidated.count(Super)) {
18003baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        Entries = F.remove(Entries, MR);
1801a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose        break;
1802a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      }
1803a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1804a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1805a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1806a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  return state->set<CStringLength>(Entries);
1807a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1808a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
180918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekvoid CStringChecker::checkLiveSymbols(const ProgramState *state,
1810183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                      SymbolReaper &SR) const {
1811a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  // Mark all symbols in our string length map as valid.
1812a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1813a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1814a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1815a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1816a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal Len = I.getData();
1817d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose
1818d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose    for (SVal::symbol_iterator si = Len.symbol_begin(), se = Len.symbol_end();
1819d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose         si != se; ++si)
1820d5af0e17b00ab2ee6a8c1f352bb9eeb1cc5b2d07Jordy Rose      SR.markInUse(*si);
1821a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1822a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1823a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1824183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CStringChecker::checkDeadSymbols(SymbolReaper &SR,
1825183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                      CheckerContext &C) const {
1826a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (!SR.hasDeadSymbols())
1827a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return;
1828a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
182918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *state = C.getState();
1830a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap Entries = state->get<CStringLength>();
1831a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  if (Entries.isEmpty())
1832a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    return;
1833a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1834a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1835a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1836a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose       I != E; ++I) {
1837a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    SVal Len = I.getData();
1838a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    if (SymbolRef Sym = Len.getAsSymbol()) {
1839a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose      if (SR.isDead(Sym))
18403baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek        Entries = F.remove(Entries, I.getKey());
1841a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose    }
1842a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  }
1843a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose
1844a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose  state = state->set<CStringLength>(Entries);
1845d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  C.generateNode(state);
1846a5261549754fab80e30e893d8fa706bfb31e430aJordy Rose}
1847183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
1848183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid ento::registerCStringChecker(CheckerManager &mgr) {
1849183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  mgr.registerChecker<CStringChecker>();
1850183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
1851