blob: 4f9c641edfd6793884df55acfae86125f58cbf19 [file] [log] [blame]
Jordy Rose134a2362010-07-06 23:11:01 +00001//= CStringChecker.h - Checks calls to C string functions ----------*- C++ -*-//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This defines CStringChecker, which is an assortment of checks on calls
11// to functions in <string.h>.
12//
13//===----------------------------------------------------------------------===//
14
Argyrios Kyrtzidis2d3905f2011-02-15 21:25:03 +000015#include "ClangSACheckers.h"
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000016#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis507ff532011-02-17 21:39:17 +000017#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000018#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Ted Kremenekf8cbac42011-02-10 01:03:03 +000019#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Ted Kremenekf8cbac42011-02-10 01:03:03 +000020#include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h"
Jordy Rose134a2362010-07-06 23:11:01 +000021#include "llvm/ADT/StringSwitch.h"
22
23using namespace clang;
Ted Kremenek98857c92010-12-23 07:20:52 +000024using namespace ento;
Jordy Rose134a2362010-07-06 23:11:01 +000025
26namespace {
Argyrios Kyrtzidis6a5674f2011-03-01 01:16:21 +000027class CStringChecker : public Checker< eval::Call,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000028 check::PreStmt<DeclStmt>,
29 check::LiveSymbols,
30 check::DeadSymbols,
31 check::RegionChanges
32 > {
33 mutable llvm::OwningPtr<BugType> BT_Null, BT_Bounds, BT_BoundsWrite,
34 BT_Overlap, BT_NotCString;
Jordy Rose134a2362010-07-06 23:11:01 +000035public:
Jordy Rose134a2362010-07-06 23:11:01 +000036 static void *getTag() { static int tag; return &tag; }
37
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000038 bool evalCall(const CallExpr *CE, CheckerContext &C) const;
39 void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
40 void checkLiveSymbols(const GRState *state, SymbolReaper &SR) const;
41 void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
42 bool wantsRegionChangeUpdate(const GRState *state) const;
Jordy Rose2a2e21c2010-08-14 21:02:52 +000043
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000044 const GRState *checkRegionChanges(const GRState *state,
45 const MemRegion * const *Begin,
46 const MemRegion * const *End) const;
Jordy Rose134a2362010-07-06 23:11:01 +000047
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000048 typedef void (CStringChecker::*FnCheck)(CheckerContext &,
49 const CallExpr *) const;
Jordy Rose134a2362010-07-06 23:11:01 +000050
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000051 void evalMemcpy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani79d74142011-03-31 21:36:53 +000052 void evalMempcpy(CheckerContext &C, const CallExpr *CE) const;
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000053 void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
54 void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani79d74142011-03-31 21:36:53 +000055 void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
56 const GRState *state,
Jordy Rosed5d2e502010-07-08 23:57:29 +000057 const Expr *Size, const Expr *Source, const Expr *Dest,
Lenny Maiorani79d74142011-03-31 21:36:53 +000058 bool Restricted = false,
59 bool IsMempcpy = false) const;
Jordy Rosed5d2e502010-07-08 23:57:29 +000060
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000061 void evalMemcmp(CheckerContext &C, const CallExpr *CE) const;
Jordy Rose134a2362010-07-06 23:11:01 +000062
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000063 void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
64 void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenek280a01f2011-02-22 04:55:05 +000065 void evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000066 bool IsStrnlen = false) const;
Jordy Roseb052e8f2010-07-27 01:37:31 +000067
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000068 void evalStrcpy(CheckerContext &C, const CallExpr *CE) const;
69 void evalStrncpy(CheckerContext &C, const CallExpr *CE) const;
70 void evalStpcpy(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenekfb1a79a2011-02-22 04:58:34 +000071 void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd,
Lenny Maiorani467dbd52011-04-09 15:12:58 +000072 bool isBounded, bool isAppending) const;
73
74 void evalStrcat(CheckerContext &C, const CallExpr *CE) const;
75 void evalStrncat(CheckerContext &C, const CallExpr *CE) const;
Jordy Rose722f5582010-08-16 07:51:42 +000076
Lenny Maioranif3539ad2011-04-12 17:08:43 +000077 void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranie553e402011-04-25 22:21:00 +000078 void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani4af23c82011-04-28 15:09:11 +000079 void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani0b510272011-05-02 19:05:49 +000080 void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranie553e402011-04-25 22:21:00 +000081 void evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maiorani4af23c82011-04-28 15:09:11 +000082 bool isBounded = false, bool ignoreCase = false) const;
Lenny Maioranif3539ad2011-04-12 17:08:43 +000083
Jordy Rose134a2362010-07-06 23:11:01 +000084 // Utility methods
Jordy Rosed5d2e502010-07-08 23:57:29 +000085 std::pair<const GRState*, const GRState*>
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000086 static assumeZero(CheckerContext &C,
87 const GRState *state, SVal V, QualType Ty);
Jordy Rosed5d2e502010-07-08 23:57:29 +000088
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000089 static const GRState *setCStringLength(const GRState *state,
90 const MemRegion *MR, SVal strLength);
91 static SVal getCStringLengthForRegion(CheckerContext &C,
92 const GRState *&state,
93 const Expr *Ex, const MemRegion *MR);
Ted Kremenek90af9092010-12-02 07:49:45 +000094 SVal getCStringLength(CheckerContext &C, const GRState *&state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +000095 const Expr *Ex, SVal Buf) const;
Jordy Roseb052e8f2010-07-27 01:37:31 +000096
Lenny Maioranif3539ad2011-04-12 17:08:43 +000097 const StringLiteral *getCStringLiteral(CheckerContext &C,
98 const GRState *&state,
99 const Expr *expr,
100 SVal val) const;
101
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000102 static const GRState *InvalidateBuffer(CheckerContext &C,
103 const GRState *state,
104 const Expr *Ex, SVal V);
Jordy Rose722f5582010-08-16 07:51:42 +0000105
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000106 static bool SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
107 const MemRegion *MR);
Jordy Roseb052e8f2010-07-27 01:37:31 +0000108
109 // Re-usable checks
Ted Kremenek90af9092010-12-02 07:49:45 +0000110 const GRState *checkNonNull(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000111 const Expr *S, SVal l) const;
Jordy Rose134a2362010-07-06 23:11:01 +0000112 const GRState *CheckLocation(CheckerContext &C, const GRState *state,
Jordy Rose722f5582010-08-16 07:51:42 +0000113 const Expr *S, SVal l,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000114 bool IsDestination = false) const;
Jordy Rose134a2362010-07-06 23:11:01 +0000115 const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
116 const Expr *Size,
117 const Expr *FirstBuf,
Jordy Rose722f5582010-08-16 07:51:42 +0000118 const Expr *SecondBuf = NULL,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000119 bool FirstIsDestination = false) const;
Jordy Rose134a2362010-07-06 23:11:01 +0000120 const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
Jordy Rosed5d2e502010-07-08 23:57:29 +0000121 const Expr *Size, const Expr *First,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000122 const Expr *Second) const;
Ted Kremenek90af9092010-12-02 07:49:45 +0000123 void emitOverlapBug(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000124 const Stmt *First, const Stmt *Second) const;
Jordy Rose134a2362010-07-06 23:11:01 +0000125};
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000126
127class CStringLength {
128public:
129 typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
130};
Jordy Rose134a2362010-07-06 23:11:01 +0000131} //end anonymous namespace
132
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000133namespace clang {
Ted Kremenek98857c92010-12-23 07:20:52 +0000134namespace ento {
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000135 template <>
136 struct GRStateTrait<CStringLength>
137 : public GRStatePartialTrait<CStringLength::EntryMap> {
138 static void *GDMIndex() { return CStringChecker::getTag(); }
139 };
140}
Argyrios Kyrtzidisca08fba2010-12-22 18:53:20 +0000141}
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000142
Jordy Rosed5d2e502010-07-08 23:57:29 +0000143//===----------------------------------------------------------------------===//
144// Individual checks and utility methods.
145//===----------------------------------------------------------------------===//
146
147std::pair<const GRState*, const GRState*>
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000148CStringChecker::assumeZero(CheckerContext &C, const GRState *state, SVal V,
Jordy Rosed5d2e502010-07-08 23:57:29 +0000149 QualType Ty) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000150 DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
151 if (!val)
Jordy Rosed5d2e502010-07-08 23:57:29 +0000152 return std::pair<const GRState*, const GRState *>(state, state);
Jordy Rose33c829a2010-07-07 07:48:06 +0000153
Ted Kremenek90af9092010-12-02 07:49:45 +0000154 SValBuilder &svalBuilder = C.getSValBuilder();
155 DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
156 return state->assume(svalBuilder.evalEQ(state, *val, zero));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000157}
Jordy Rose33c829a2010-07-07 07:48:06 +0000158
Ted Kremenek90af9092010-12-02 07:49:45 +0000159const GRState *CStringChecker::checkNonNull(CheckerContext &C,
Jordy Rosed5d2e502010-07-08 23:57:29 +0000160 const GRState *state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000161 const Expr *S, SVal l) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000162 // If a previous check has failed, propagate the failure.
163 if (!state)
164 return NULL;
165
166 const GRState *stateNull, *stateNonNull;
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000167 llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
Jordy Rosed5d2e502010-07-08 23:57:29 +0000168
169 if (stateNull && !stateNonNull) {
Ted Kremenek750b7ac2010-12-20 21:19:09 +0000170 ExplodedNode *N = C.generateSink(stateNull);
Jordy Rose33c829a2010-07-07 07:48:06 +0000171 if (!N)
172 return NULL;
173
Jordy Rosed5d2e502010-07-08 23:57:29 +0000174 if (!BT_Null)
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000175 BT_Null.reset(new BuiltinBug("API",
176 "Null pointer argument in call to byte string function"));
Jordy Rose33c829a2010-07-07 07:48:06 +0000177
178 // Generate a report for this bug.
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000179 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null.get());
Jordy Rose33c829a2010-07-07 07:48:06 +0000180 EnhancedBugReport *report = new EnhancedBugReport(*BT,
181 BT->getDescription(), N);
182
183 report->addRange(S->getSourceRange());
184 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
185 C.EmitReport(report);
186 return NULL;
187 }
188
189 // From here on, assume that the value is non-null.
Jordy Rosed5d2e502010-07-08 23:57:29 +0000190 assert(stateNonNull);
191 return stateNonNull;
Jordy Rose33c829a2010-07-07 07:48:06 +0000192}
193
Jordy Rose134a2362010-07-06 23:11:01 +0000194// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
195const GRState *CStringChecker::CheckLocation(CheckerContext &C,
196 const GRState *state,
Jordy Rose722f5582010-08-16 07:51:42 +0000197 const Expr *S, SVal l,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000198 bool IsDestination) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000199 // If a previous check has failed, propagate the failure.
200 if (!state)
201 return NULL;
202
Jordy Rose134a2362010-07-06 23:11:01 +0000203 // Check for out of bound array element access.
204 const MemRegion *R = l.getAsRegion();
205 if (!R)
206 return state;
207
Jordy Rose134a2362010-07-06 23:11:01 +0000208 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
209 if (!ER)
210 return state;
211
Zhongxing Xu8de0a3d2010-08-11 06:10:55 +0000212 assert(ER->getValueType() == C.getASTContext().CharTy &&
Jordy Rose134a2362010-07-06 23:11:01 +0000213 "CheckLocation should only be called with char* ElementRegions");
214
215 // Get the size of the array.
Ted Kremenek90af9092010-12-02 07:49:45 +0000216 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
217 SValBuilder &svalBuilder = C.getSValBuilder();
218 SVal Extent = svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
Jordy Rose134a2362010-07-06 23:11:01 +0000219 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
220
221 // Get the index of the accessed element.
Gabor Greif230ddf32010-09-09 10:51:37 +0000222 DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
Jordy Rose134a2362010-07-06 23:11:01 +0000223
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000224 const GRState *StInBound = state->assumeInBound(Idx, Size, true);
225 const GRState *StOutBound = state->assumeInBound(Idx, Size, false);
Jordy Rose134a2362010-07-06 23:11:01 +0000226 if (StOutBound && !StInBound) {
Ted Kremenek750b7ac2010-12-20 21:19:09 +0000227 ExplodedNode *N = C.generateSink(StOutBound);
Jordy Rose134a2362010-07-06 23:11:01 +0000228 if (!N)
229 return NULL;
230
Jordy Rose722f5582010-08-16 07:51:42 +0000231 BuiltinBug *BT;
232 if (IsDestination) {
233 if (!BT_BoundsWrite) {
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000234 BT_BoundsWrite.reset(new BuiltinBug("Out-of-bound array access",
235 "Byte string function overflows destination buffer"));
Jordy Rose722f5582010-08-16 07:51:42 +0000236 }
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000237 BT = static_cast<BuiltinBug*>(BT_BoundsWrite.get());
Jordy Rose722f5582010-08-16 07:51:42 +0000238 } else {
239 if (!BT_Bounds) {
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000240 BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
241 "Byte string function accesses out-of-bound array element"));
Jordy Rose722f5582010-08-16 07:51:42 +0000242 }
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000243 BT = static_cast<BuiltinBug*>(BT_Bounds.get());
Jordy Rose722f5582010-08-16 07:51:42 +0000244 }
Jordy Rose134a2362010-07-06 23:11:01 +0000245
246 // FIXME: It would be nice to eventually make this diagnostic more clear,
247 // e.g., by referencing the original declaration or by saying *why* this
248 // reference is outside the range.
249
250 // Generate a report for this bug.
Jordy Rose134a2362010-07-06 23:11:01 +0000251 RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N);
252
253 report->addRange(S->getSourceRange());
254 C.EmitReport(report);
255 return NULL;
256 }
257
258 // Array bound check succeeded. From this point forward the array bound
259 // should always succeed.
260 return StInBound;
261}
262
263const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
264 const GRState *state,
265 const Expr *Size,
266 const Expr *FirstBuf,
Jordy Rose722f5582010-08-16 07:51:42 +0000267 const Expr *SecondBuf,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000268 bool FirstIsDestination) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000269 // If a previous check has failed, propagate the failure.
270 if (!state)
271 return NULL;
272
Ted Kremenek90af9092010-12-02 07:49:45 +0000273 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rose134a2362010-07-06 23:11:01 +0000274 ASTContext &Ctx = C.getASTContext();
275
Ted Kremenek90af9092010-12-02 07:49:45 +0000276 QualType sizeTy = Size->getType();
Jordy Rose134a2362010-07-06 23:11:01 +0000277 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
278
Jordy Rose33c829a2010-07-07 07:48:06 +0000279 // Check that the first buffer is non-null.
280 SVal BufVal = state->getSVal(FirstBuf);
Ted Kremenek90af9092010-12-02 07:49:45 +0000281 state = checkNonNull(C, state, FirstBuf, BufVal);
Jordy Rose33c829a2010-07-07 07:48:06 +0000282 if (!state)
283 return NULL;
284
Jordy Rosed5d2e502010-07-08 23:57:29 +0000285 // Get the access length and make sure it is known.
286 SVal LengthVal = state->getSVal(Size);
287 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
288 if (!Length)
289 return state;
290
Jordy Rose134a2362010-07-06 23:11:01 +0000291 // Compute the offset of the last element to be accessed: size-1.
Ted Kremenek90af9092010-12-02 07:49:45 +0000292 NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
293 NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
294 *Length, One, sizeTy));
Jordy Rose134a2362010-07-06 23:11:01 +0000295
Chris Lattner57540c52011-04-15 05:22:18 +0000296 // Check that the first buffer is sufficiently long.
Ted Kremenek90af9092010-12-02 07:49:45 +0000297 SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
Jordy Roseafdb0532010-08-05 23:11:30 +0000298 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000299 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
300 LastOffset, PtrTy);
Jordy Rose722f5582010-08-16 07:51:42 +0000301 state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
Jordy Rose134a2362010-07-06 23:11:01 +0000302
Jordy Roseafdb0532010-08-05 23:11:30 +0000303 // If the buffer isn't large enough, abort.
304 if (!state)
305 return NULL;
306 }
Jordy Rose134a2362010-07-06 23:11:01 +0000307
308 // If there's a second buffer, check it as well.
309 if (SecondBuf) {
310 BufVal = state->getSVal(SecondBuf);
Ted Kremenek90af9092010-12-02 07:49:45 +0000311 state = checkNonNull(C, state, SecondBuf, BufVal);
Jordy Rose33c829a2010-07-07 07:48:06 +0000312 if (!state)
313 return NULL;
314
Ted Kremenek90af9092010-12-02 07:49:45 +0000315 BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
Jordy Roseafdb0532010-08-05 23:11:30 +0000316 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000317 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
318 LastOffset, PtrTy);
Jordy Roseafdb0532010-08-05 23:11:30 +0000319 state = CheckLocation(C, state, SecondBuf, BufEnd);
320 }
Jordy Rose134a2362010-07-06 23:11:01 +0000321 }
322
323 // Large enough or not, return this state!
324 return state;
325}
326
327const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
328 const GRState *state,
Jordy Rosed5d2e502010-07-08 23:57:29 +0000329 const Expr *Size,
Jordy Rose134a2362010-07-06 23:11:01 +0000330 const Expr *First,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000331 const Expr *Second) const {
Jordy Rose134a2362010-07-06 23:11:01 +0000332 // Do a simple check for overlap: if the two arguments are from the same
333 // buffer, see if the end of the first is greater than the start of the second
334 // or vice versa.
335
Jordy Rosed5d2e502010-07-08 23:57:29 +0000336 // If a previous check has failed, propagate the failure.
337 if (!state)
338 return NULL;
339
Jordy Rose134a2362010-07-06 23:11:01 +0000340 const GRState *stateTrue, *stateFalse;
341
342 // Get the buffer values and make sure they're known locations.
Ted Kremenek90af9092010-12-02 07:49:45 +0000343 SVal firstVal = state->getSVal(First);
344 SVal secondVal = state->getSVal(Second);
Jordy Rose134a2362010-07-06 23:11:01 +0000345
Ted Kremenek90af9092010-12-02 07:49:45 +0000346 Loc *firstLoc = dyn_cast<Loc>(&firstVal);
347 if (!firstLoc)
Jordy Rose134a2362010-07-06 23:11:01 +0000348 return state;
349
Ted Kremenek90af9092010-12-02 07:49:45 +0000350 Loc *secondLoc = dyn_cast<Loc>(&secondVal);
351 if (!secondLoc)
Jordy Rose134a2362010-07-06 23:11:01 +0000352 return state;
353
354 // Are the two values the same?
Ted Kremenek90af9092010-12-02 07:49:45 +0000355 SValBuilder &svalBuilder = C.getSValBuilder();
356 llvm::tie(stateTrue, stateFalse) =
357 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
Jordy Rose134a2362010-07-06 23:11:01 +0000358
359 if (stateTrue && !stateFalse) {
360 // If the values are known to be equal, that's automatically an overlap.
Ted Kremenek90af9092010-12-02 07:49:45 +0000361 emitOverlapBug(C, stateTrue, First, Second);
Jordy Rose134a2362010-07-06 23:11:01 +0000362 return NULL;
363 }
364
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000365 // assume the two expressions are not equal.
Jordy Rose134a2362010-07-06 23:11:01 +0000366 assert(stateFalse);
367 state = stateFalse;
368
369 // Which value comes first?
Ted Kremenek90af9092010-12-02 07:49:45 +0000370 ASTContext &Ctx = svalBuilder.getContext();
371 QualType cmpTy = Ctx.IntTy;
372 SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
373 *firstLoc, *secondLoc, cmpTy);
374 DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
375 if (!reverseTest)
Jordy Rose134a2362010-07-06 23:11:01 +0000376 return state;
377
Ted Kremenek90af9092010-12-02 07:49:45 +0000378 llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
Jordy Rose134a2362010-07-06 23:11:01 +0000379 if (stateTrue) {
380 if (stateFalse) {
381 // If we don't know which one comes first, we can't perform this test.
382 return state;
383 } else {
Ted Kremenek90af9092010-12-02 07:49:45 +0000384 // Switch the values so that firstVal is before secondVal.
385 Loc *tmpLoc = firstLoc;
386 firstLoc = secondLoc;
387 secondLoc = tmpLoc;
Jordy Rose134a2362010-07-06 23:11:01 +0000388
389 // Switch the Exprs as well, so that they still correspond.
390 const Expr *tmpExpr = First;
391 First = Second;
392 Second = tmpExpr;
393 }
394 }
395
396 // Get the length, and make sure it too is known.
397 SVal LengthVal = state->getSVal(Size);
398 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
399 if (!Length)
400 return state;
401
402 // Convert the first buffer's start address to char*.
403 // Bail out if the cast fails.
404 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
Ted Kremenek90af9092010-12-02 07:49:45 +0000405 SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, First->getType());
Jordy Rose134a2362010-07-06 23:11:01 +0000406 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
407 if (!FirstStartLoc)
408 return state;
409
410 // Compute the end of the first buffer. Bail out if THAT fails.
Ted Kremenek90af9092010-12-02 07:49:45 +0000411 SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
Jordy Rose134a2362010-07-06 23:11:01 +0000412 *FirstStartLoc, *Length, CharPtrTy);
413 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
414 if (!FirstEndLoc)
415 return state;
416
417 // Is the end of the first buffer past the start of the second buffer?
Ted Kremenek90af9092010-12-02 07:49:45 +0000418 SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
419 *FirstEndLoc, *secondLoc, cmpTy);
Jordy Rose134a2362010-07-06 23:11:01 +0000420 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
421 if (!OverlapTest)
422 return state;
423
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000424 llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
Jordy Rose134a2362010-07-06 23:11:01 +0000425
426 if (stateTrue && !stateFalse) {
427 // Overlap!
Ted Kremenek90af9092010-12-02 07:49:45 +0000428 emitOverlapBug(C, stateTrue, First, Second);
Jordy Rose134a2362010-07-06 23:11:01 +0000429 return NULL;
430 }
431
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000432 // assume the two expressions don't overlap.
Jordy Rose134a2362010-07-06 23:11:01 +0000433 assert(stateFalse);
434 return stateFalse;
435}
436
Ted Kremenek90af9092010-12-02 07:49:45 +0000437void CStringChecker::emitOverlapBug(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000438 const Stmt *First, const Stmt *Second) const {
Ted Kremenek750b7ac2010-12-20 21:19:09 +0000439 ExplodedNode *N = C.generateSink(state);
Jordy Rose134a2362010-07-06 23:11:01 +0000440 if (!N)
441 return;
442
443 if (!BT_Overlap)
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000444 BT_Overlap.reset(new BugType("Unix API", "Improper arguments"));
Jordy Rose134a2362010-07-06 23:11:01 +0000445
446 // Generate a report for this bug.
447 RangedBugReport *report =
448 new RangedBugReport(*BT_Overlap,
449 "Arguments must not be overlapping buffers", N);
450 report->addRange(First->getSourceRange());
451 report->addRange(Second->getSourceRange());
452
453 C.EmitReport(report);
454}
455
Ted Kremenek90af9092010-12-02 07:49:45 +0000456const GRState *CStringChecker::setCStringLength(const GRState *state,
Jordy Rose722f5582010-08-16 07:51:42 +0000457 const MemRegion *MR,
Ted Kremenek90af9092010-12-02 07:49:45 +0000458 SVal strLength) {
459 assert(!strLength.isUndef() && "Attempt to set an undefined string length");
460 if (strLength.isUnknown())
Jordy Rose722f5582010-08-16 07:51:42 +0000461 return state;
462
463 MR = MR->StripCasts();
464
465 switch (MR->getKind()) {
466 case MemRegion::StringRegionKind:
467 // FIXME: This can happen if we strcpy() into a string region. This is
468 // undefined [C99 6.4.5p6], but we should still warn about it.
469 return state;
470
471 case MemRegion::SymbolicRegionKind:
472 case MemRegion::AllocaRegionKind:
473 case MemRegion::VarRegionKind:
474 case MemRegion::FieldRegionKind:
475 case MemRegion::ObjCIvarRegionKind:
Ted Kremenek90af9092010-12-02 07:49:45 +0000476 return state->set<CStringLength>(MR, strLength);
Jordy Rose722f5582010-08-16 07:51:42 +0000477
478 case MemRegion::ElementRegionKind:
479 // FIXME: Handle element regions by upper-bounding the parent region's
480 // string length.
481 return state;
482
483 default:
484 // Other regions (mostly non-data) can't have a reliable C string length.
485 // For now, just ignore the change.
486 // FIXME: These are rare but not impossible. We should output some kind of
487 // warning for things like strcpy((char[]){'a', 0}, "b");
488 return state;
489 }
490}
491
Ted Kremenek90af9092010-12-02 07:49:45 +0000492SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000493 const GRState *&state,
494 const Expr *Ex,
495 const MemRegion *MR) {
496 // If there's a recorded length, go ahead and return it.
497 const SVal *Recorded = state->get<CStringLength>(MR);
498 if (Recorded)
499 return *Recorded;
500
501 // Otherwise, get a new symbol and update the state.
502 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenek90af9092010-12-02 07:49:45 +0000503 SValBuilder &svalBuilder = C.getSValBuilder();
504 QualType sizeTy = svalBuilder.getContext().getSizeType();
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000505 SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
506 MR, Ex, sizeTy, Count);
Ted Kremenek90af9092010-12-02 07:49:45 +0000507 state = state->set<CStringLength>(MR, strLength);
508 return strLength;
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000509}
510
Ted Kremenek90af9092010-12-02 07:49:45 +0000511SVal CStringChecker::getCStringLength(CheckerContext &C, const GRState *&state,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000512 const Expr *Ex, SVal Buf) const {
Jordy Roseb052e8f2010-07-27 01:37:31 +0000513 const MemRegion *MR = Buf.getAsRegion();
514 if (!MR) {
515 // If we can't get a region, see if it's something we /know/ isn't a
516 // C string. In the context of locations, the only time we can issue such
517 // a warning is for labels.
518 if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
Ted Kremenek750b7ac2010-12-20 21:19:09 +0000519 if (ExplodedNode *N = C.generateNode(state)) {
Jordy Roseb052e8f2010-07-27 01:37:31 +0000520 if (!BT_NotCString)
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000521 BT_NotCString.reset(new BuiltinBug("API",
522 "Argument is not a null-terminated string."));
Jordy Roseb052e8f2010-07-27 01:37:31 +0000523
524 llvm::SmallString<120> buf;
525 llvm::raw_svector_ostream os(buf);
526 os << "Argument to byte string function is the address of the label '"
Chris Lattner5a9b1ec2011-02-17 05:38:27 +0000527 << Label->getLabel()->getName()
Jordy Roseb052e8f2010-07-27 01:37:31 +0000528 << "', which is not a null-terminated string";
529
530 // Generate a report for this bug.
531 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
532 os.str(), N);
533
534 report->addRange(Ex->getSourceRange());
535 C.EmitReport(report);
536 }
537
538 return UndefinedVal();
539 }
540
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000541 // If it's not a region and not a label, give up.
542 return UnknownVal();
Jordy Roseb052e8f2010-07-27 01:37:31 +0000543 }
544
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000545 // If we have a region, strip casts from it and see if we can figure out
546 // its length. For anything we can't figure out, just return UnknownVal.
547 MR = MR->StripCasts();
548
549 switch (MR->getKind()) {
550 case MemRegion::StringRegionKind: {
551 // Modifying the contents of string regions is undefined [C99 6.4.5p6],
552 // so we can assume that the byte length is the correct C string length.
Ted Kremenek90af9092010-12-02 07:49:45 +0000553 SValBuilder &svalBuilder = C.getSValBuilder();
554 QualType sizeTy = svalBuilder.getContext().getSizeType();
555 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
556 return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000557 }
558 case MemRegion::SymbolicRegionKind:
559 case MemRegion::AllocaRegionKind:
560 case MemRegion::VarRegionKind:
561 case MemRegion::FieldRegionKind:
562 case MemRegion::ObjCIvarRegionKind:
Ted Kremenek90af9092010-12-02 07:49:45 +0000563 return getCStringLengthForRegion(C, state, Ex, MR);
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000564 case MemRegion::CompoundLiteralRegionKind:
565 // FIXME: Can we track this? Is it necessary?
566 return UnknownVal();
567 case MemRegion::ElementRegionKind:
568 // FIXME: How can we handle this? It's not good enough to subtract the
569 // offset from the base string length; consider "123\x00567" and &a[5].
570 return UnknownVal();
571 default:
572 // Other regions (mostly non-data) can't have a reliable C string length.
573 // In this case, an error is emitted and UndefinedVal is returned.
574 // The caller should always be prepared to handle this case.
Ted Kremenek750b7ac2010-12-20 21:19:09 +0000575 if (ExplodedNode *N = C.generateNode(state)) {
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000576 if (!BT_NotCString)
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000577 BT_NotCString.reset(new BuiltinBug("API",
578 "Argument is not a null-terminated string."));
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000579
580 llvm::SmallString<120> buf;
581 llvm::raw_svector_ostream os(buf);
582
583 os << "Argument to byte string function is ";
584
585 if (SummarizeRegion(os, C.getASTContext(), MR))
586 os << ", which is not a null-terminated string";
587 else
588 os << "not a null-terminated string";
589
590 // Generate a report for this bug.
591 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
592 os.str(), N);
593
594 report->addRange(Ex->getSourceRange());
595 C.EmitReport(report);
596 }
597
598 return UndefinedVal();
599 }
Jordy Roseb052e8f2010-07-27 01:37:31 +0000600}
601
Lenny Maioranif3539ad2011-04-12 17:08:43 +0000602const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
603 const GRState *&state, const Expr *expr, SVal val) const {
604
605 // Get the memory region pointed to by the val.
606 const MemRegion *bufRegion = val.getAsRegion();
607 if (!bufRegion)
608 return NULL;
609
610 // Strip casts off the memory region.
611 bufRegion = bufRegion->StripCasts();
612
613 // Cast the memory region to a string region.
614 const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
615 if (!strRegion)
616 return NULL;
617
618 // Return the actual string in the string region.
619 return strRegion->getStringLiteral();
620}
621
Jordy Rose722f5582010-08-16 07:51:42 +0000622const GRState *CStringChecker::InvalidateBuffer(CheckerContext &C,
623 const GRState *state,
624 const Expr *E, SVal V) {
625 Loc *L = dyn_cast<Loc>(&V);
626 if (!L)
627 return state;
628
629 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
630 // some assumptions about the value that CFRefCount can't. Even so, it should
631 // probably be refactored.
632 if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
633 const MemRegion *R = MR->getRegion()->StripCasts();
634
635 // Are we dealing with an ElementRegion? If so, we should be invalidating
636 // the super-region.
637 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
638 R = ER->getSuperRegion();
639 // FIXME: What about layers of ElementRegions?
640 }
641
642 // Invalidate this region.
643 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenekeddeba02011-02-11 19:48:15 +0000644 return state->invalidateRegion(R, E, Count, NULL);
Jordy Rose722f5582010-08-16 07:51:42 +0000645 }
646
647 // If we have a non-region value by chance, just remove the binding.
648 // FIXME: is this necessary or correct? This handles the non-Region
649 // cases. Is it ever valid to store to these?
650 return state->unbindLoc(*L);
651}
652
Jordy Roseb052e8f2010-07-27 01:37:31 +0000653bool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
654 const MemRegion *MR) {
655 const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
656 if (!TR)
657 return false;
658
659 switch (TR->getKind()) {
660 case MemRegion::FunctionTextRegionKind: {
661 const FunctionDecl *FD = cast<FunctionTextRegion>(TR)->getDecl();
662 if (FD)
663 os << "the address of the function '" << FD << "'";
664 else
665 os << "the address of a function";
666 return true;
667 }
668 case MemRegion::BlockTextRegionKind:
669 os << "block text";
670 return true;
671 case MemRegion::BlockDataRegionKind:
672 os << "a block";
673 return true;
674 case MemRegion::CXXThisRegionKind:
Zhongxing Xu03207162010-11-26 08:52:48 +0000675 case MemRegion::CXXTempObjectRegionKind:
676 os << "a C++ temp object of type " << TR->getValueType().getAsString();
Jordy Roseb052e8f2010-07-27 01:37:31 +0000677 return true;
678 case MemRegion::VarRegionKind:
Zhongxing Xu8de0a3d2010-08-11 06:10:55 +0000679 os << "a variable of type" << TR->getValueType().getAsString();
Jordy Roseb052e8f2010-07-27 01:37:31 +0000680 return true;
681 case MemRegion::FieldRegionKind:
Zhongxing Xu8de0a3d2010-08-11 06:10:55 +0000682 os << "a field of type " << TR->getValueType().getAsString();
Jordy Roseb052e8f2010-07-27 01:37:31 +0000683 return true;
684 case MemRegion::ObjCIvarRegionKind:
Zhongxing Xu8de0a3d2010-08-11 06:10:55 +0000685 os << "an instance variable of type " << TR->getValueType().getAsString();
Jordy Roseb052e8f2010-07-27 01:37:31 +0000686 return true;
687 default:
688 return false;
689 }
690}
691
Jordy Rosed5d2e502010-07-08 23:57:29 +0000692//===----------------------------------------------------------------------===//
Ted Kremenekdc891422010-12-01 21:57:22 +0000693// evaluation of individual function calls.
Jordy Rosed5d2e502010-07-08 23:57:29 +0000694//===----------------------------------------------------------------------===//
695
Lenny Maiorani79d74142011-03-31 21:36:53 +0000696void CStringChecker::evalCopyCommon(CheckerContext &C,
697 const CallExpr *CE,
698 const GRState *state,
Jordy Rosed5d2e502010-07-08 23:57:29 +0000699 const Expr *Size, const Expr *Dest,
Lenny Maiorani79d74142011-03-31 21:36:53 +0000700 const Expr *Source, bool Restricted,
701 bool IsMempcpy) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000702 // See if the size argument is zero.
Ted Kremenek90af9092010-12-02 07:49:45 +0000703 SVal sizeVal = state->getSVal(Size);
704 QualType sizeTy = Size->getType();
Jordy Rosed5d2e502010-07-08 23:57:29 +0000705
Ted Kremenek90af9092010-12-02 07:49:45 +0000706 const GRState *stateZeroSize, *stateNonZeroSize;
707 llvm::tie(stateZeroSize, stateNonZeroSize) = assumeZero(C, state, sizeVal, sizeTy);
Jordy Rosed5d2e502010-07-08 23:57:29 +0000708
Lenny Maiorani79d74142011-03-31 21:36:53 +0000709 // Get the value of the Dest.
710 SVal destVal = state->getSVal(Dest);
711
712 // If the size is zero, there won't be any actual memory access, so
713 // just bind the return value to the destination buffer and return.
714 if (stateZeroSize) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000715 C.addTransition(stateZeroSize);
Lenny Maiorani79d74142011-03-31 21:36:53 +0000716 if (IsMempcpy)
717 state->BindExpr(CE, destVal);
718 else
719 state->BindExpr(CE, sizeVal);
720 return;
721 }
Jordy Rosed5d2e502010-07-08 23:57:29 +0000722
723 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenek90af9092010-12-02 07:49:45 +0000724 if (stateNonZeroSize) {
Lenny Maiorani79d74142011-03-31 21:36:53 +0000725
726 // Ensure the destination is not null. If it is NULL there will be a
727 // NULL pointer dereference.
728 state = checkNonNull(C, state, Dest, destVal);
729 if (!state)
730 return;
731
732 // Get the value of the Src.
733 SVal srcVal = state->getSVal(Source);
734
735 // Ensure the source is not null. If it is NULL there will be a
736 // NULL pointer dereference.
737 state = checkNonNull(C, state, Source, srcVal);
738 if (!state)
739 return;
740
741 // Ensure the buffers do not overlap.
Ted Kremenek90af9092010-12-02 07:49:45 +0000742 state = stateNonZeroSize;
Jordy Rose722f5582010-08-16 07:51:42 +0000743 state = CheckBufferAccess(C, state, Size, Dest, Source,
744 /* FirstIsDst = */ true);
Jordy Rosed5d2e502010-07-08 23:57:29 +0000745 if (Restricted)
746 state = CheckOverlap(C, state, Size, Dest, Source);
Jordy Rose722f5582010-08-16 07:51:42 +0000747
748 if (state) {
Lenny Maiorani79d74142011-03-31 21:36:53 +0000749
750 // If this is mempcpy, get the byte after the last byte copied and
751 // bind the expr.
752 if (IsMempcpy) {
753 loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
754
755 // Get the length to copy.
756 SVal lenVal = state->getSVal(Size);
757 NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&lenVal);
758
759 // Get the byte after the last byte copied.
760 SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
761 *destRegVal,
762 *lenValNonLoc,
763 Dest->getType());
764
765 // The byte after the last byte copied is the return value.
766 state = state->BindExpr(CE, lastElement);
767 }
768
Jordy Rose722f5582010-08-16 07:51:42 +0000769 // Invalidate the destination.
770 // FIXME: Even if we can't perfectly model the copy, we should see if we
771 // can use LazyCompoundVals to copy the source values into the destination.
772 // This would probably remove any existing bindings past the end of the
773 // copied region, but that's still an improvement over blank invalidation.
774 state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000775 C.addTransition(state);
Jordy Rose722f5582010-08-16 07:51:42 +0000776 }
Jordy Rosed5d2e502010-07-08 23:57:29 +0000777 }
778}
779
780
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000781void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rose134a2362010-07-06 23:11:01 +0000782 // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
Jordy Rose134a2362010-07-06 23:11:01 +0000783 // The return value is the address of the destination buffer.
Jordy Rosed5d2e502010-07-08 23:57:29 +0000784 const Expr *Dest = CE->getArg(0);
785 const GRState *state = C.getState();
786 state = state->BindExpr(CE, state->getSVal(Dest));
Lenny Maiorani79d74142011-03-31 21:36:53 +0000787 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
788}
789
790void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
791 // void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
792 // The return value is a pointer to the byte following the last written byte.
793 const Expr *Dest = CE->getArg(0);
794 const GRState *state = C.getState();
795
796 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
Jordy Rose134a2362010-07-06 23:11:01 +0000797}
798
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000799void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000800 // void *memmove(void *dst, const void *src, size_t n);
801 // The return value is the address of the destination buffer.
802 const Expr *Dest = CE->getArg(0);
803 const GRState *state = C.getState();
804 state = state->BindExpr(CE, state->getSVal(Dest));
Lenny Maiorani79d74142011-03-31 21:36:53 +0000805 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000806}
807
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000808void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed5d2e502010-07-08 23:57:29 +0000809 // void bcopy(const void *src, void *dst, size_t n);
Lenny Maiorani79d74142011-03-31 21:36:53 +0000810 evalCopyCommon(C, CE, C.getState(),
811 CE->getArg(2), CE->getArg(1), CE->getArg(0));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000812}
813
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000814void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
Jordy Rose65136fb2010-07-07 08:15:01 +0000815 // int memcmp(const void *s1, const void *s2, size_t n);
816 const Expr *Left = CE->getArg(0);
817 const Expr *Right = CE->getArg(1);
818 const Expr *Size = CE->getArg(2);
819
820 const GRState *state = C.getState();
Ted Kremenek90af9092010-12-02 07:49:45 +0000821 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rose65136fb2010-07-07 08:15:01 +0000822
Jordy Rosed5d2e502010-07-08 23:57:29 +0000823 // See if the size argument is zero.
Ted Kremenek90af9092010-12-02 07:49:45 +0000824 SVal sizeVal = state->getSVal(Size);
825 QualType sizeTy = Size->getType();
Jordy Rose65136fb2010-07-07 08:15:01 +0000826
Ted Kremenek90af9092010-12-02 07:49:45 +0000827 const GRState *stateZeroSize, *stateNonZeroSize;
828 llvm::tie(stateZeroSize, stateNonZeroSize) =
829 assumeZero(C, state, sizeVal, sizeTy);
Jordy Rose65136fb2010-07-07 08:15:01 +0000830
Jordy Rosed5d2e502010-07-08 23:57:29 +0000831 // If the size can be zero, the result will be 0 in that case, and we don't
832 // have to check either of the buffers.
Ted Kremenek90af9092010-12-02 07:49:45 +0000833 if (stateZeroSize) {
834 state = stateZeroSize;
835 state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000836 C.addTransition(state);
Jordy Rose65136fb2010-07-07 08:15:01 +0000837 }
838
Jordy Rosed5d2e502010-07-08 23:57:29 +0000839 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenek90af9092010-12-02 07:49:45 +0000840 if (stateNonZeroSize) {
841 state = stateNonZeroSize;
Jordy Rosed5d2e502010-07-08 23:57:29 +0000842 // If we know the two buffers are the same, we know the result is 0.
843 // First, get the two buffers' addresses. Another checker will have already
844 // made sure they're not undefined.
845 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
846 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
Jordy Rose65136fb2010-07-07 08:15:01 +0000847
Jordy Rosed5d2e502010-07-08 23:57:29 +0000848 // See if they are the same.
Ted Kremenek90af9092010-12-02 07:49:45 +0000849 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
Jordy Rosed5d2e502010-07-08 23:57:29 +0000850 const GRState *StSameBuf, *StNotSameBuf;
Ted Kremenekc5bea1e2010-12-01 22:16:56 +0000851 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
Jordy Rosed5d2e502010-07-08 23:57:29 +0000852
853 // If the two arguments might be the same buffer, we know the result is zero,
854 // and we only need to check one size.
855 if (StSameBuf) {
856 state = StSameBuf;
857 state = CheckBufferAccess(C, state, Size, Left);
858 if (state) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000859 state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Jordy Rosed5d2e502010-07-08 23:57:29 +0000860 C.addTransition(state);
861 }
862 }
863
864 // If the two arguments might be different buffers, we have to check the
865 // size of both of them.
866 if (StNotSameBuf) {
867 state = StNotSameBuf;
868 state = CheckBufferAccess(C, state, Size, Left, Right);
869 if (state) {
870 // The return value is the comparison result, which we don't know.
871 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenek90af9092010-12-02 07:49:45 +0000872 SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rosed5d2e502010-07-08 23:57:29 +0000873 state = state->BindExpr(CE, CmpV);
874 C.addTransition(state);
875 }
876 }
877 }
Jordy Rose65136fb2010-07-07 08:15:01 +0000878}
879
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000880void CStringChecker::evalstrLength(CheckerContext &C,
881 const CallExpr *CE) const {
Jordy Roseb052e8f2010-07-27 01:37:31 +0000882 // size_t strlen(const char *s);
Ted Kremenek280a01f2011-02-22 04:55:05 +0000883 evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
884}
885
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000886void CStringChecker::evalstrnLength(CheckerContext &C,
887 const CallExpr *CE) const {
Ted Kremenek280a01f2011-02-22 04:55:05 +0000888 // size_t strnlen(const char *s, size_t maxlen);
889 evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
890}
891
892void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000893 bool IsStrnlen) const {
Jordy Roseb052e8f2010-07-27 01:37:31 +0000894 const GRState *state = C.getState();
895 const Expr *Arg = CE->getArg(0);
896 SVal ArgVal = state->getSVal(Arg);
897
898 // Check that the argument is non-null.
Ted Kremenek90af9092010-12-02 07:49:45 +0000899 state = checkNonNull(C, state, Arg, ArgVal);
Jordy Roseb052e8f2010-07-27 01:37:31 +0000900
901 if (state) {
Ted Kremenek90af9092010-12-02 07:49:45 +0000902 SVal strLength = getCStringLength(C, state, Arg, ArgVal);
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000903
904 // If the argument isn't a valid C string, there's no valid state to
905 // transition to.
Ted Kremenek90af9092010-12-02 07:49:45 +0000906 if (strLength.isUndef())
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000907 return;
908
Ted Kremenek280a01f2011-02-22 04:55:05 +0000909 // If the check is for strnlen() then bind the return value to no more than
910 // the maxlen value.
911 if (IsStrnlen) {
912 const Expr *maxlenExpr = CE->getArg(1);
913 SVal maxlenVal = state->getSVal(maxlenExpr);
914
915 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
916 NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
917
918 QualType cmpTy = C.getSValBuilder().getContext().IntTy;
919 const GRState *stateTrue, *stateFalse;
920
921 // Check if the strLength is greater than or equal to the maxlen
922 llvm::tie(stateTrue, stateFalse) =
923 state->assume(cast<DefinedOrUnknownSVal>
924 (C.getSValBuilder().evalBinOpNN(state, BO_GE,
925 *strLengthNL, *maxlenValNL,
926 cmpTy)));
927
928 // If the strLength is greater than or equal to the maxlen, set strLength
929 // to maxlen
930 if (stateTrue && !stateFalse) {
931 strLength = maxlenVal;
932 }
933 }
934
Ted Kremenek90af9092010-12-02 07:49:45 +0000935 // If getCStringLength couldn't figure out the length, conjure a return
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000936 // value, so it can be used in constraints, at least.
Ted Kremenek90af9092010-12-02 07:49:45 +0000937 if (strLength.isUnknown()) {
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000938 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenek90af9092010-12-02 07:49:45 +0000939 strLength = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
Jordy Roseb052e8f2010-07-27 01:37:31 +0000940 }
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000941
942 // Bind the return value.
Ted Kremenek90af9092010-12-02 07:49:45 +0000943 state = state->BindExpr(CE, strLength);
Jordy Rose2a2e21c2010-08-14 21:02:52 +0000944 C.addTransition(state);
Jordy Roseb052e8f2010-07-27 01:37:31 +0000945 }
946}
947
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000948void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rose722f5582010-08-16 07:51:42 +0000949 // char *strcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani467dbd52011-04-09 15:12:58 +0000950 evalStrcpyCommon(C, CE,
951 /* returnEnd = */ false,
952 /* isBounded = */ false,
953 /* isAppending = */ false);
Ted Kremenekfb1a79a2011-02-22 04:58:34 +0000954}
955
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000956void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
Ted Kremenekfb1a79a2011-02-22 04:58:34 +0000957 // char *strcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani467dbd52011-04-09 15:12:58 +0000958 evalStrcpyCommon(C, CE,
959 /* returnEnd = */ false,
960 /* isBounded = */ true,
961 /* isAppending = */ false);
Jordy Rose722f5582010-08-16 07:51:42 +0000962}
963
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +0000964void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rose722f5582010-08-16 07:51:42 +0000965 // char *stpcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani467dbd52011-04-09 15:12:58 +0000966 evalStrcpyCommon(C, CE,
967 /* returnEnd = */ true,
968 /* isBounded = */ false,
969 /* isAppending = */ false);
970}
971
972void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
973 //char *strcat(char *restrict s1, const char *restrict s2);
974 evalStrcpyCommon(C, CE,
975 /* returnEnd = */ false,
976 /* isBounded = */ false,
977 /* isAppending = */ true);
978}
979
980void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
981 //char *strncat(char *restrict s1, const char *restrict s2, size_t n);
982 evalStrcpyCommon(C, CE,
983 /* returnEnd = */ false,
984 /* isBounded = */ true,
985 /* isAppending = */ true);
Jordy Rose722f5582010-08-16 07:51:42 +0000986}
987
Ted Kremenekdc891422010-12-01 21:57:22 +0000988void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maiorani467dbd52011-04-09 15:12:58 +0000989 bool returnEnd, bool isBounded,
990 bool isAppending) const {
Jordy Rose722f5582010-08-16 07:51:42 +0000991 const GRState *state = C.getState();
992
Lenny Maiorani467dbd52011-04-09 15:12:58 +0000993 // Check that the destination is non-null.
Jordy Rose722f5582010-08-16 07:51:42 +0000994 const Expr *Dst = CE->getArg(0);
995 SVal DstVal = state->getSVal(Dst);
996
Ted Kremenek90af9092010-12-02 07:49:45 +0000997 state = checkNonNull(C, state, Dst, DstVal);
Jordy Rose722f5582010-08-16 07:51:42 +0000998 if (!state)
999 return;
1000
1001 // Check that the source is non-null.
Ted Kremenek90af9092010-12-02 07:49:45 +00001002 const Expr *srcExpr = CE->getArg(1);
1003 SVal srcVal = state->getSVal(srcExpr);
1004 state = checkNonNull(C, state, srcExpr, srcVal);
Jordy Rose722f5582010-08-16 07:51:42 +00001005 if (!state)
1006 return;
1007
1008 // Get the string length of the source.
Ted Kremenek90af9092010-12-02 07:49:45 +00001009 SVal strLength = getCStringLength(C, state, srcExpr, srcVal);
Jordy Rose722f5582010-08-16 07:51:42 +00001010
1011 // If the source isn't a valid C string, give up.
Ted Kremenek90af9092010-12-02 07:49:45 +00001012 if (strLength.isUndef())
Jordy Rose722f5582010-08-16 07:51:42 +00001013 return;
1014
Lenny Maiorani467dbd52011-04-09 15:12:58 +00001015 // If the function is strncpy, strncat, etc... it is bounded.
1016 if (isBounded) {
1017 // Get the max number of characters to copy.
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001018 const Expr *lenExpr = CE->getArg(2);
1019 SVal lenVal = state->getSVal(lenExpr);
1020
Lenny Maioranied2cc6c2011-04-28 18:59:43 +00001021 // Cast the length to a NonLoc SVal. If it is not a NonLoc then give up.
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001022 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
Lenny Maioranied2cc6c2011-04-28 18:59:43 +00001023 if (!strLengthNL)
1024 return;
1025
1026 // Cast the max length to a NonLoc SVal. If it is not a NonLoc then give up.
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001027 NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
Lenny Maioranied2cc6c2011-04-28 18:59:43 +00001028 if (!lenValNL)
1029 return;
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001030
1031 QualType cmpTy = C.getSValBuilder().getContext().IntTy;
1032 const GRState *stateTrue, *stateFalse;
1033
Lenny Maiorani467dbd52011-04-09 15:12:58 +00001034 // Check if the max number to copy is less than the length of the src.
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001035 llvm::tie(stateTrue, stateFalse) =
1036 state->assume(cast<DefinedOrUnknownSVal>
1037 (C.getSValBuilder().evalBinOpNN(state, BO_GT,
1038 *strLengthNL, *lenValNL,
1039 cmpTy)));
1040
1041 if (stateTrue) {
1042 // Max number to copy is less than the length of the src, so the actual
1043 // strLength copied is the max number arg.
1044 strLength = lenVal;
1045 }
1046 }
1047
Lenny Maiorani467dbd52011-04-09 15:12:58 +00001048 // If this is an appending function (strcat, strncat...) then set the
1049 // string length to strlen(src) + strlen(dst) since the buffer will
1050 // ultimately contain both.
1051 if (isAppending) {
1052 // Get the string length of the destination, or give up.
1053 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
1054 if (dstStrLength.isUndef())
1055 return;
1056
1057 NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&strLength);
1058 NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
1059
1060 // If src or dst cast to NonLoc is NULL, give up.
1061 if ((!srcStrLengthNL) || (!dstStrLengthNL))
1062 return;
1063
1064 QualType addTy = C.getSValBuilder().getContext().getSizeType();
1065
1066 strLength = C.getSValBuilder().evalBinOpNN(state, BO_Add,
1067 *srcStrLengthNL, *dstStrLengthNL,
1068 addTy);
1069 }
1070
Ted Kremenek90af9092010-12-02 07:49:45 +00001071 SVal Result = (returnEnd ? UnknownVal() : DstVal);
Jordy Rose722f5582010-08-16 07:51:42 +00001072
1073 // If the destination is a MemRegion, try to check for a buffer overflow and
1074 // record the new string length.
Ted Kremenek90af9092010-12-02 07:49:45 +00001075 if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
Jordy Rose722f5582010-08-16 07:51:42 +00001076 // If the length is known, we can check for an overflow.
Ted Kremenek90af9092010-12-02 07:49:45 +00001077 if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&strLength)) {
1078 SVal lastElement =
1079 C.getSValBuilder().evalBinOpLN(state, BO_Add, *dstRegVal,
1080 *knownStrLength, Dst->getType());
Jordy Rose722f5582010-08-16 07:51:42 +00001081
Ted Kremenek90af9092010-12-02 07:49:45 +00001082 state = CheckLocation(C, state, Dst, lastElement, /* IsDst = */ true);
Jordy Rose722f5582010-08-16 07:51:42 +00001083 if (!state)
1084 return;
1085
1086 // If this is a stpcpy-style copy, the last element is the return value.
Ted Kremenek90af9092010-12-02 07:49:45 +00001087 if (returnEnd)
1088 Result = lastElement;
Jordy Rose722f5582010-08-16 07:51:42 +00001089 }
1090
1091 // Invalidate the destination. This must happen before we set the C string
1092 // length because invalidation will clear the length.
1093 // FIXME: Even if we can't perfectly model the copy, we should see if we
1094 // can use LazyCompoundVals to copy the source values into the destination.
1095 // This would probably remove any existing bindings past the end of the
1096 // string, but that's still an improvement over blank invalidation.
Ted Kremenek90af9092010-12-02 07:49:45 +00001097 state = InvalidateBuffer(C, state, Dst, *dstRegVal);
Jordy Rose722f5582010-08-16 07:51:42 +00001098
1099 // Set the C string length of the destination.
Ted Kremenek90af9092010-12-02 07:49:45 +00001100 state = setCStringLength(state, dstRegVal->getRegion(), strLength);
Jordy Rose722f5582010-08-16 07:51:42 +00001101 }
1102
1103 // If this is a stpcpy-style copy, but we were unable to check for a buffer
1104 // overflow, we still need a result. Conjure a return value.
Ted Kremenek90af9092010-12-02 07:49:45 +00001105 if (returnEnd && Result.isUnknown()) {
1106 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rose722f5582010-08-16 07:51:42 +00001107 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenek90af9092010-12-02 07:49:45 +00001108 strLength = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rose722f5582010-08-16 07:51:42 +00001109 }
1110
1111 // Set the return value.
1112 state = state->BindExpr(CE, Result);
1113 C.addTransition(state);
1114}
1115
Lenny Maioranif3539ad2011-04-12 17:08:43 +00001116void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
1117 //int strcmp(const char *restrict s1, const char *restrict s2);
Lenny Maiorani4af23c82011-04-28 15:09:11 +00001118 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
Lenny Maioranie553e402011-04-25 22:21:00 +00001119}
Lenny Maioranif3539ad2011-04-12 17:08:43 +00001120
Lenny Maioranie553e402011-04-25 22:21:00 +00001121void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
1122 //int strncmp(const char *restrict s1, const char *restrict s2, size_t n);
Lenny Maiorani4af23c82011-04-28 15:09:11 +00001123 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
1124}
1125
1126void CStringChecker::evalStrcasecmp(CheckerContext &C,
1127 const CallExpr *CE) const {
1128 //int strcasecmp(const char *restrict s1, const char *restrict s2);
1129 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
Lenny Maioranie553e402011-04-25 22:21:00 +00001130}
1131
Lenny Maiorani0b510272011-05-02 19:05:49 +00001132void CStringChecker::evalStrncasecmp(CheckerContext &C,
1133 const CallExpr *CE) const {
1134 //int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n);
1135 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true);
1136}
1137
Lenny Maioranie553e402011-04-25 22:21:00 +00001138void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maiorani4af23c82011-04-28 15:09:11 +00001139 bool isBounded, bool ignoreCase) const {
Lenny Maioranif3539ad2011-04-12 17:08:43 +00001140 const GRState *state = C.getState();
1141
1142 // Check that the first string is non-null
1143 const Expr *s1 = CE->getArg(0);
1144 SVal s1Val = state->getSVal(s1);
1145 state = checkNonNull(C, state, s1, s1Val);
1146 if (!state)
1147 return;
1148
1149 // Check that the second string is non-null.
1150 const Expr *s2 = CE->getArg(1);
1151 SVal s2Val = state->getSVal(s2);
1152 state = checkNonNull(C, state, s2, s2Val);
1153 if (!state)
1154 return;
1155
1156 // Get the string length of the first string or give up.
1157 SVal s1Length = getCStringLength(C, state, s1, s1Val);
1158 if (s1Length.isUndef())
1159 return;
1160
1161 // Get the string length of the second string or give up.
1162 SVal s2Length = getCStringLength(C, state, s2, s2Val);
1163 if (s2Length.isUndef())
1164 return;
1165
1166 // Get the string literal of the first string.
1167 const StringLiteral *s1StrLiteral = getCStringLiteral(C, state, s1, s1Val);
1168 if (!s1StrLiteral)
1169 return;
1170 llvm::StringRef s1StrRef = s1StrLiteral->getString();
1171
1172 // Get the string literal of the second string.
1173 const StringLiteral *s2StrLiteral = getCStringLiteral(C, state, s2, s2Val);
1174 if (!s2StrLiteral)
1175 return;
1176 llvm::StringRef s2StrRef = s2StrLiteral->getString();
1177
Lenny Maioranie553e402011-04-25 22:21:00 +00001178 int result;
1179 if (isBounded) {
1180 // Get the max number of characters to compare.
1181 const Expr *lenExpr = CE->getArg(2);
1182 SVal lenVal = state->getSVal(lenExpr);
1183
1184 // Dynamically cast the length to a ConcreteInt. If it is not a ConcreteInt
1185 // then give up, otherwise get the value and use it as the bounds.
1186 nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&lenVal);
1187 if (!CI)
1188 return;
1189 llvm::APSInt lenInt(CI->getValue());
1190
Lenny Maiorani0b510272011-05-02 19:05:49 +00001191 // Create substrings of each to compare the prefix.
1192 s1StrRef = s1StrRef.substr(0, (size_t)lenInt.getLimitedValue());
1193 s2StrRef = s2StrRef.substr(0, (size_t)lenInt.getLimitedValue());
1194 }
Lenny Maiorani4af23c82011-04-28 15:09:11 +00001195
Lenny Maiorani0b510272011-05-02 19:05:49 +00001196 if (ignoreCase) {
1197 // Compare string 1 to string 2 the same way strcasecmp() does.
1198 result = s1StrRef.compare_lower(s2StrRef);
Lenny Maioranie553e402011-04-25 22:21:00 +00001199 } else {
1200 // Compare string 1 to string 2 the same way strcmp() does.
Lenny Maiorani0b510272011-05-02 19:05:49 +00001201 result = s1StrRef.compare(s2StrRef);
Lenny Maioranie553e402011-04-25 22:21:00 +00001202 }
Lenny Maioranif3539ad2011-04-12 17:08:43 +00001203
1204 // Build the SVal of the comparison to bind the return value.
1205 SValBuilder &svalBuilder = C.getSValBuilder();
1206 QualType intTy = svalBuilder.getContext().IntTy;
1207 SVal resultVal = svalBuilder.makeIntVal(result, intTy);
1208
1209 // Bind the return value of the expression.
1210 // Set the return value.
1211 state = state->BindExpr(CE, resultVal);
1212 C.addTransition(state);
1213}
1214
Jordy Rosed5d2e502010-07-08 23:57:29 +00001215//===----------------------------------------------------------------------===//
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001216// The driver method, and other Checker callbacks.
Jordy Rosed5d2e502010-07-08 23:57:29 +00001217//===----------------------------------------------------------------------===//
Jordy Rose134a2362010-07-06 23:11:01 +00001218
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001219bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
Jordy Rose134a2362010-07-06 23:11:01 +00001220 // Get the callee. All the functions we care about are C functions
1221 // with simple identifiers.
1222 const GRState *state = C.getState();
1223 const Expr *Callee = CE->getCallee();
1224 const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
1225
1226 if (!FD)
1227 return false;
1228
1229 // Get the name of the callee. If it's a builtin, strip off the prefix.
Douglas Gregor4b8eca82010-11-01 23:16:05 +00001230 IdentifierInfo *II = FD->getIdentifier();
1231 if (!II) // if no identifier, not a simple C function
1232 return false;
1233 llvm::StringRef Name = II->getName();
Jordy Rose134a2362010-07-06 23:11:01 +00001234 if (Name.startswith("__builtin_"))
1235 Name = Name.substr(10);
1236
Ted Kremenekdc891422010-12-01 21:57:22 +00001237 FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
1238 .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
Lenny Maiorani79d74142011-03-31 21:36:53 +00001239 .Case("mempcpy", &CStringChecker::evalMempcpy)
Ted Kremenekdc891422010-12-01 21:57:22 +00001240 .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
1241 .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
1242 .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
Ted Kremenekfb1a79a2011-02-22 04:58:34 +00001243 .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
Ted Kremenekdc891422010-12-01 21:57:22 +00001244 .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
Lenny Maiorani467dbd52011-04-09 15:12:58 +00001245 .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat)
1246 .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat)
Ted Kremenek90af9092010-12-02 07:49:45 +00001247 .Case("strlen", &CStringChecker::evalstrLength)
Ted Kremenek280a01f2011-02-22 04:55:05 +00001248 .Case("strnlen", &CStringChecker::evalstrnLength)
Lenny Maioranif3539ad2011-04-12 17:08:43 +00001249 .Case("strcmp", &CStringChecker::evalStrcmp)
Lenny Maioranie553e402011-04-25 22:21:00 +00001250 .Case("strncmp", &CStringChecker::evalStrncmp)
Lenny Maiorani4af23c82011-04-28 15:09:11 +00001251 .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
Lenny Maiorani0b510272011-05-02 19:05:49 +00001252 .Case("strncasecmp", &CStringChecker::evalStrncasecmp)
Ted Kremenekdc891422010-12-01 21:57:22 +00001253 .Case("bcopy", &CStringChecker::evalBcopy)
Jordy Rose134a2362010-07-06 23:11:01 +00001254 .Default(NULL);
1255
Jordy Rosed5d2e502010-07-08 23:57:29 +00001256 // If the callee isn't a string function, let another checker handle it.
Ted Kremenekdc891422010-12-01 21:57:22 +00001257 if (!evalFunction)
Jordy Rose134a2362010-07-06 23:11:01 +00001258 return false;
1259
Jordy Rosed5d2e502010-07-08 23:57:29 +00001260 // Check and evaluate the call.
Ted Kremenekdc891422010-12-01 21:57:22 +00001261 (this->*evalFunction)(C, CE);
Jordy Rose134a2362010-07-06 23:11:01 +00001262 return true;
1263}
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001264
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001265void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001266 // Record string length for char a[] = "abc";
1267 const GRState *state = C.getState();
1268
1269 for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
1270 I != E; ++I) {
1271 const VarDecl *D = dyn_cast<VarDecl>(*I);
1272 if (!D)
1273 continue;
1274
1275 // FIXME: Handle array fields of structs.
1276 if (!D->getType()->isArrayType())
1277 continue;
1278
1279 const Expr *Init = D->getInit();
1280 if (!Init)
1281 continue;
1282 if (!isa<StringLiteral>(Init))
1283 continue;
1284
1285 Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
1286 const MemRegion *MR = VarLoc.getAsRegion();
1287 if (!MR)
1288 continue;
1289
1290 SVal StrVal = state->getSVal(Init);
1291 assert(StrVal.isValid() && "Initializer string is unknown or undefined");
Ted Kremenek90af9092010-12-02 07:49:45 +00001292 DefinedOrUnknownSVal strLength
1293 = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001294
Ted Kremenek90af9092010-12-02 07:49:45 +00001295 state = state->set<CStringLength>(MR, strLength);
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001296 }
1297
1298 C.addTransition(state);
1299}
1300
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001301bool CStringChecker::wantsRegionChangeUpdate(const GRState *state) const {
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001302 CStringLength::EntryMap Entries = state->get<CStringLength>();
1303 return !Entries.isEmpty();
1304}
1305
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001306const GRState *
1307CStringChecker::checkRegionChanges(const GRState *state,
1308 const MemRegion * const *Begin,
1309 const MemRegion * const *End) const {
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001310 CStringLength::EntryMap Entries = state->get<CStringLength>();
1311 if (Entries.isEmpty())
1312 return state;
1313
1314 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
1315 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
1316
1317 // First build sets for the changed regions and their super-regions.
1318 for ( ; Begin != End; ++Begin) {
1319 const MemRegion *MR = *Begin;
1320 Invalidated.insert(MR);
1321
1322 SuperRegions.insert(MR);
1323 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
1324 MR = SR->getSuperRegion();
1325 SuperRegions.insert(MR);
1326 }
1327 }
1328
1329 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1330
1331 // Then loop over the entries in the current state.
1332 for (CStringLength::EntryMap::iterator I = Entries.begin(),
1333 E = Entries.end(); I != E; ++I) {
1334 const MemRegion *MR = I.getKey();
1335
1336 // Is this entry for a super-region of a changed region?
1337 if (SuperRegions.count(MR)) {
Ted Kremenekb3b56c62010-11-24 00:54:37 +00001338 Entries = F.remove(Entries, MR);
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001339 continue;
1340 }
1341
1342 // Is this entry for a sub-region of a changed region?
1343 const MemRegion *Super = MR;
1344 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
1345 Super = SR->getSuperRegion();
1346 if (Invalidated.count(Super)) {
Ted Kremenekb3b56c62010-11-24 00:54:37 +00001347 Entries = F.remove(Entries, MR);
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001348 break;
1349 }
1350 }
1351 }
1352
1353 return state->set<CStringLength>(Entries);
1354}
1355
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001356void CStringChecker::checkLiveSymbols(const GRState *state,
1357 SymbolReaper &SR) const {
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001358 // Mark all symbols in our string length map as valid.
1359 CStringLength::EntryMap Entries = state->get<CStringLength>();
1360
1361 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1362 I != E; ++I) {
1363 SVal Len = I.getData();
1364 if (SymbolRef Sym = Len.getAsSymbol())
1365 SR.markInUse(Sym);
1366 }
1367}
1368
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001369void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
1370 CheckerContext &C) const {
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001371 if (!SR.hasDeadSymbols())
1372 return;
1373
1374 const GRState *state = C.getState();
1375 CStringLength::EntryMap Entries = state->get<CStringLength>();
1376 if (Entries.isEmpty())
1377 return;
1378
1379 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1380 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1381 I != E; ++I) {
1382 SVal Len = I.getData();
1383 if (SymbolRef Sym = Len.getAsSymbol()) {
1384 if (SR.isDead(Sym))
Ted Kremenekb3b56c62010-11-24 00:54:37 +00001385 Entries = F.remove(Entries, I.getKey());
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001386 }
1387 }
1388
1389 state = state->set<CStringLength>(Entries);
Ted Kremenek750b7ac2010-12-20 21:19:09 +00001390 C.generateNode(state);
Jordy Rose2a2e21c2010-08-14 21:02:52 +00001391}
Argyrios Kyrtzidisc26f15d2011-02-24 01:05:30 +00001392
1393void ento::registerCStringChecker(CheckerManager &mgr) {
1394 mgr.registerChecker<CStringChecker>();
1395}