blob: 534b887f3b26c3148bd05ddf3709cd6dbbc3051f [file] [log] [blame]
Jordy Roseccbf7ee2010-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 Kyrtzidisa0decc92011-02-15 21:25:03 +000015#include "ClangSACheckers.h"
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000016#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis695fb502011-02-17 21:39:17 +000017#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000018#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Ted Kremenek9b663712011-02-10 01:03:03 +000019#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Ted Kremenek9b663712011-02-10 01:03:03 +000020#include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h"
Jordy Roseccbf7ee2010-07-06 23:11:01 +000021#include "llvm/ADT/StringSwitch.h"
22
23using namespace clang;
Ted Kremenek9ef65372010-12-23 07:20:52 +000024using namespace ento;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000025
26namespace {
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000027class CStringChecker : public Checker< eval::Call,
Argyrios Kyrtzidis183ff982011-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 Roseccbf7ee2010-07-06 23:11:01 +000035public:
Jordy Roseccbf7ee2010-07-06 23:11:01 +000036 static void *getTag() { static int tag; return &tag; }
37
Argyrios Kyrtzidis183ff982011-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 Rosea5261542010-08-14 21:02:52 +000043
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000044 const GRState *checkRegionChanges(const GRState *state,
45 const MemRegion * const *Begin,
46 const MemRegion * const *End) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000047
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000048 typedef void (CStringChecker::*FnCheck)(CheckerContext &,
49 const CallExpr *) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000050
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000051 void evalMemcpy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranib8b875b2011-03-31 21:36:53 +000052 void evalMempcpy(CheckerContext &C, const CallExpr *CE) const;
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000053 void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
54 void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranib8b875b2011-03-31 21:36:53 +000055 void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
56 const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +000057 const Expr *Size, const Expr *Source, const Expr *Dest,
Lenny Maioranib8b875b2011-03-31 21:36:53 +000058 bool Restricted = false,
59 bool IsMempcpy = false) const;
Jordy Rosed325ffb2010-07-08 23:57:29 +000060
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000061 void evalMemcmp(CheckerContext &C, const CallExpr *CE) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000062
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000063 void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
64 void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenekbe4242c2011-02-22 04:55:05 +000065 void evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000066 bool IsStrnlen = false) const;
Jordy Rose19c5dd12010-07-27 01:37:31 +000067
Argyrios Kyrtzidis183ff982011-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 Kremenek0ef473f2011-02-22 04:58:34 +000071 void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd,
Lenny Maiorani067bbd02011-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 Rosee64f3112010-08-16 07:51:42 +000076
Lenny Maiorani318dd922011-04-12 17:08:43 +000077 void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani357f6ee2011-04-25 22:21:00 +000078 void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranibd1d16a2011-04-28 15:09:11 +000079 void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani357f6ee2011-04-25 22:21:00 +000080 void evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maioranibd1d16a2011-04-28 15:09:11 +000081 bool isBounded = false, bool ignoreCase = false) const;
Lenny Maiorani318dd922011-04-12 17:08:43 +000082
Jordy Roseccbf7ee2010-07-06 23:11:01 +000083 // Utility methods
Jordy Rosed325ffb2010-07-08 23:57:29 +000084 std::pair<const GRState*, const GRState*>
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000085 static assumeZero(CheckerContext &C,
86 const GRState *state, SVal V, QualType Ty);
Jordy Rosed325ffb2010-07-08 23:57:29 +000087
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000088 static const GRState *setCStringLength(const GRState *state,
89 const MemRegion *MR, SVal strLength);
90 static SVal getCStringLengthForRegion(CheckerContext &C,
91 const GRState *&state,
92 const Expr *Ex, const MemRegion *MR);
Ted Kremenekc8413fd2010-12-02 07:49:45 +000093 SVal getCStringLength(CheckerContext &C, const GRState *&state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000094 const Expr *Ex, SVal Buf) const;
Jordy Rose19c5dd12010-07-27 01:37:31 +000095
Lenny Maiorani318dd922011-04-12 17:08:43 +000096 const StringLiteral *getCStringLiteral(CheckerContext &C,
97 const GRState *&state,
98 const Expr *expr,
99 SVal val) const;
100
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000101 static const GRState *InvalidateBuffer(CheckerContext &C,
102 const GRState *state,
103 const Expr *Ex, SVal V);
Jordy Rosee64f3112010-08-16 07:51:42 +0000104
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000105 static bool SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
106 const MemRegion *MR);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000107
108 // Re-usable checks
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000109 const GRState *checkNonNull(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000110 const Expr *S, SVal l) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000111 const GRState *CheckLocation(CheckerContext &C, const GRState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000112 const Expr *S, SVal l,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000113 bool IsDestination = false) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000114 const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
115 const Expr *Size,
116 const Expr *FirstBuf,
Jordy Rosee64f3112010-08-16 07:51:42 +0000117 const Expr *SecondBuf = NULL,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000118 bool FirstIsDestination = false) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000119 const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000120 const Expr *Size, const Expr *First,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000121 const Expr *Second) const;
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000122 void emitOverlapBug(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000123 const Stmt *First, const Stmt *Second) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000124};
Jordy Rosea5261542010-08-14 21:02:52 +0000125
126class CStringLength {
127public:
128 typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
129};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000130} //end anonymous namespace
131
Jordy Rosea5261542010-08-14 21:02:52 +0000132namespace clang {
Ted Kremenek9ef65372010-12-23 07:20:52 +0000133namespace ento {
Jordy Rosea5261542010-08-14 21:02:52 +0000134 template <>
135 struct GRStateTrait<CStringLength>
136 : public GRStatePartialTrait<CStringLength::EntryMap> {
137 static void *GDMIndex() { return CStringChecker::getTag(); }
138 };
139}
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +0000140}
Jordy Rosea5261542010-08-14 21:02:52 +0000141
Jordy Rosed325ffb2010-07-08 23:57:29 +0000142//===----------------------------------------------------------------------===//
143// Individual checks and utility methods.
144//===----------------------------------------------------------------------===//
145
146std::pair<const GRState*, const GRState*>
Ted Kremenek28f47b92010-12-01 22:16:56 +0000147CStringChecker::assumeZero(CheckerContext &C, const GRState *state, SVal V,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000148 QualType Ty) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000149 DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
150 if (!val)
Jordy Rosed325ffb2010-07-08 23:57:29 +0000151 return std::pair<const GRState*, const GRState *>(state, state);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000152
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000153 SValBuilder &svalBuilder = C.getSValBuilder();
154 DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
155 return state->assume(svalBuilder.evalEQ(state, *val, zero));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000156}
Jordy Rosea6b808c2010-07-07 07:48:06 +0000157
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000158const GRState *CStringChecker::checkNonNull(CheckerContext &C,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000159 const GRState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000160 const Expr *S, SVal l) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000161 // If a previous check has failed, propagate the failure.
162 if (!state)
163 return NULL;
164
165 const GRState *stateNull, *stateNonNull;
Ted Kremenek28f47b92010-12-01 22:16:56 +0000166 llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
Jordy Rosed325ffb2010-07-08 23:57:29 +0000167
168 if (stateNull && !stateNonNull) {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000169 ExplodedNode *N = C.generateSink(stateNull);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000170 if (!N)
171 return NULL;
172
Jordy Rosed325ffb2010-07-08 23:57:29 +0000173 if (!BT_Null)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000174 BT_Null.reset(new BuiltinBug("API",
175 "Null pointer argument in call to byte string function"));
Jordy Rosea6b808c2010-07-07 07:48:06 +0000176
177 // Generate a report for this bug.
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000178 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null.get());
Jordy Rosea6b808c2010-07-07 07:48:06 +0000179 EnhancedBugReport *report = new EnhancedBugReport(*BT,
180 BT->getDescription(), N);
181
182 report->addRange(S->getSourceRange());
183 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
184 C.EmitReport(report);
185 return NULL;
186 }
187
188 // From here on, assume that the value is non-null.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000189 assert(stateNonNull);
190 return stateNonNull;
Jordy Rosea6b808c2010-07-07 07:48:06 +0000191}
192
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000193// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
194const GRState *CStringChecker::CheckLocation(CheckerContext &C,
195 const GRState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000196 const Expr *S, SVal l,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000197 bool IsDestination) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000198 // If a previous check has failed, propagate the failure.
199 if (!state)
200 return NULL;
201
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000202 // Check for out of bound array element access.
203 const MemRegion *R = l.getAsRegion();
204 if (!R)
205 return state;
206
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000207 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
208 if (!ER)
209 return state;
210
Zhongxing Xu018220c2010-08-11 06:10:55 +0000211 assert(ER->getValueType() == C.getASTContext().CharTy &&
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000212 "CheckLocation should only be called with char* ElementRegions");
213
214 // Get the size of the array.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000215 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
216 SValBuilder &svalBuilder = C.getSValBuilder();
217 SVal Extent = svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000218 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
219
220 // Get the index of the accessed element.
Gabor Greif89b06582010-09-09 10:51:37 +0000221 DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000222
Ted Kremenek28f47b92010-12-01 22:16:56 +0000223 const GRState *StInBound = state->assumeInBound(Idx, Size, true);
224 const GRState *StOutBound = state->assumeInBound(Idx, Size, false);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000225 if (StOutBound && !StInBound) {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000226 ExplodedNode *N = C.generateSink(StOutBound);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000227 if (!N)
228 return NULL;
229
Jordy Rosee64f3112010-08-16 07:51:42 +0000230 BuiltinBug *BT;
231 if (IsDestination) {
232 if (!BT_BoundsWrite) {
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000233 BT_BoundsWrite.reset(new BuiltinBug("Out-of-bound array access",
234 "Byte string function overflows destination buffer"));
Jordy Rosee64f3112010-08-16 07:51:42 +0000235 }
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000236 BT = static_cast<BuiltinBug*>(BT_BoundsWrite.get());
Jordy Rosee64f3112010-08-16 07:51:42 +0000237 } else {
238 if (!BT_Bounds) {
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000239 BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
240 "Byte string function accesses out-of-bound array element"));
Jordy Rosee64f3112010-08-16 07:51:42 +0000241 }
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000242 BT = static_cast<BuiltinBug*>(BT_Bounds.get());
Jordy Rosee64f3112010-08-16 07:51:42 +0000243 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000244
245 // FIXME: It would be nice to eventually make this diagnostic more clear,
246 // e.g., by referencing the original declaration or by saying *why* this
247 // reference is outside the range.
248
249 // Generate a report for this bug.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000250 RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N);
251
252 report->addRange(S->getSourceRange());
253 C.EmitReport(report);
254 return NULL;
255 }
256
257 // Array bound check succeeded. From this point forward the array bound
258 // should always succeed.
259 return StInBound;
260}
261
262const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
263 const GRState *state,
264 const Expr *Size,
265 const Expr *FirstBuf,
Jordy Rosee64f3112010-08-16 07:51:42 +0000266 const Expr *SecondBuf,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000267 bool FirstIsDestination) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000268 // If a previous check has failed, propagate the failure.
269 if (!state)
270 return NULL;
271
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000272 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000273 ASTContext &Ctx = C.getASTContext();
274
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000275 QualType sizeTy = Size->getType();
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000276 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
277
Jordy Rosea6b808c2010-07-07 07:48:06 +0000278 // Check that the first buffer is non-null.
279 SVal BufVal = state->getSVal(FirstBuf);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000280 state = checkNonNull(C, state, FirstBuf, BufVal);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000281 if (!state)
282 return NULL;
283
Jordy Rosed325ffb2010-07-08 23:57:29 +0000284 // Get the access length and make sure it is known.
285 SVal LengthVal = state->getSVal(Size);
286 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
287 if (!Length)
288 return state;
289
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000290 // Compute the offset of the last element to be accessed: size-1.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000291 NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
292 NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
293 *Length, One, sizeTy));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000294
Chris Lattnerfc8f0e12011-04-15 05:22:18 +0000295 // Check that the first buffer is sufficiently long.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000296 SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
Jordy Roseb6a40262010-08-05 23:11:30 +0000297 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000298 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
299 LastOffset, PtrTy);
Jordy Rosee64f3112010-08-16 07:51:42 +0000300 state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000301
Jordy Roseb6a40262010-08-05 23:11:30 +0000302 // If the buffer isn't large enough, abort.
303 if (!state)
304 return NULL;
305 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000306
307 // If there's a second buffer, check it as well.
308 if (SecondBuf) {
309 BufVal = state->getSVal(SecondBuf);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000310 state = checkNonNull(C, state, SecondBuf, BufVal);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000311 if (!state)
312 return NULL;
313
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000314 BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
Jordy Roseb6a40262010-08-05 23:11:30 +0000315 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000316 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
317 LastOffset, PtrTy);
Jordy Roseb6a40262010-08-05 23:11:30 +0000318 state = CheckLocation(C, state, SecondBuf, BufEnd);
319 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000320 }
321
322 // Large enough or not, return this state!
323 return state;
324}
325
326const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
327 const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000328 const Expr *Size,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000329 const Expr *First,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000330 const Expr *Second) const {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000331 // Do a simple check for overlap: if the two arguments are from the same
332 // buffer, see if the end of the first is greater than the start of the second
333 // or vice versa.
334
Jordy Rosed325ffb2010-07-08 23:57:29 +0000335 // If a previous check has failed, propagate the failure.
336 if (!state)
337 return NULL;
338
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000339 const GRState *stateTrue, *stateFalse;
340
341 // Get the buffer values and make sure they're known locations.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000342 SVal firstVal = state->getSVal(First);
343 SVal secondVal = state->getSVal(Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000344
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000345 Loc *firstLoc = dyn_cast<Loc>(&firstVal);
346 if (!firstLoc)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000347 return state;
348
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000349 Loc *secondLoc = dyn_cast<Loc>(&secondVal);
350 if (!secondLoc)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000351 return state;
352
353 // Are the two values the same?
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000354 SValBuilder &svalBuilder = C.getSValBuilder();
355 llvm::tie(stateTrue, stateFalse) =
356 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000357
358 if (stateTrue && !stateFalse) {
359 // If the values are known to be equal, that's automatically an overlap.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000360 emitOverlapBug(C, stateTrue, First, Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000361 return NULL;
362 }
363
Ted Kremenek28f47b92010-12-01 22:16:56 +0000364 // assume the two expressions are not equal.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000365 assert(stateFalse);
366 state = stateFalse;
367
368 // Which value comes first?
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000369 ASTContext &Ctx = svalBuilder.getContext();
370 QualType cmpTy = Ctx.IntTy;
371 SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
372 *firstLoc, *secondLoc, cmpTy);
373 DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
374 if (!reverseTest)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000375 return state;
376
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000377 llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000378 if (stateTrue) {
379 if (stateFalse) {
380 // If we don't know which one comes first, we can't perform this test.
381 return state;
382 } else {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000383 // Switch the values so that firstVal is before secondVal.
384 Loc *tmpLoc = firstLoc;
385 firstLoc = secondLoc;
386 secondLoc = tmpLoc;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000387
388 // Switch the Exprs as well, so that they still correspond.
389 const Expr *tmpExpr = First;
390 First = Second;
391 Second = tmpExpr;
392 }
393 }
394
395 // Get the length, and make sure it too is known.
396 SVal LengthVal = state->getSVal(Size);
397 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
398 if (!Length)
399 return state;
400
401 // Convert the first buffer's start address to char*.
402 // Bail out if the cast fails.
403 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000404 SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, First->getType());
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000405 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
406 if (!FirstStartLoc)
407 return state;
408
409 // Compute the end of the first buffer. Bail out if THAT fails.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000410 SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000411 *FirstStartLoc, *Length, CharPtrTy);
412 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
413 if (!FirstEndLoc)
414 return state;
415
416 // Is the end of the first buffer past the start of the second buffer?
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000417 SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
418 *FirstEndLoc, *secondLoc, cmpTy);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000419 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
420 if (!OverlapTest)
421 return state;
422
Ted Kremenek28f47b92010-12-01 22:16:56 +0000423 llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000424
425 if (stateTrue && !stateFalse) {
426 // Overlap!
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000427 emitOverlapBug(C, stateTrue, First, Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000428 return NULL;
429 }
430
Ted Kremenek28f47b92010-12-01 22:16:56 +0000431 // assume the two expressions don't overlap.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000432 assert(stateFalse);
433 return stateFalse;
434}
435
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000436void CStringChecker::emitOverlapBug(CheckerContext &C, const GRState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000437 const Stmt *First, const Stmt *Second) const {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000438 ExplodedNode *N = C.generateSink(state);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000439 if (!N)
440 return;
441
442 if (!BT_Overlap)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000443 BT_Overlap.reset(new BugType("Unix API", "Improper arguments"));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000444
445 // Generate a report for this bug.
446 RangedBugReport *report =
447 new RangedBugReport(*BT_Overlap,
448 "Arguments must not be overlapping buffers", N);
449 report->addRange(First->getSourceRange());
450 report->addRange(Second->getSourceRange());
451
452 C.EmitReport(report);
453}
454
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000455const GRState *CStringChecker::setCStringLength(const GRState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000456 const MemRegion *MR,
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000457 SVal strLength) {
458 assert(!strLength.isUndef() && "Attempt to set an undefined string length");
459 if (strLength.isUnknown())
Jordy Rosee64f3112010-08-16 07:51:42 +0000460 return state;
461
462 MR = MR->StripCasts();
463
464 switch (MR->getKind()) {
465 case MemRegion::StringRegionKind:
466 // FIXME: This can happen if we strcpy() into a string region. This is
467 // undefined [C99 6.4.5p6], but we should still warn about it.
468 return state;
469
470 case MemRegion::SymbolicRegionKind:
471 case MemRegion::AllocaRegionKind:
472 case MemRegion::VarRegionKind:
473 case MemRegion::FieldRegionKind:
474 case MemRegion::ObjCIvarRegionKind:
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000475 return state->set<CStringLength>(MR, strLength);
Jordy Rosee64f3112010-08-16 07:51:42 +0000476
477 case MemRegion::ElementRegionKind:
478 // FIXME: Handle element regions by upper-bounding the parent region's
479 // string length.
480 return state;
481
482 default:
483 // Other regions (mostly non-data) can't have a reliable C string length.
484 // For now, just ignore the change.
485 // FIXME: These are rare but not impossible. We should output some kind of
486 // warning for things like strcpy((char[]){'a', 0}, "b");
487 return state;
488 }
489}
490
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000491SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
Jordy Rosea5261542010-08-14 21:02:52 +0000492 const GRState *&state,
493 const Expr *Ex,
494 const MemRegion *MR) {
495 // If there's a recorded length, go ahead and return it.
496 const SVal *Recorded = state->get<CStringLength>(MR);
497 if (Recorded)
498 return *Recorded;
499
500 // Otherwise, get a new symbol and update the state.
501 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000502 SValBuilder &svalBuilder = C.getSValBuilder();
503 QualType sizeTy = svalBuilder.getContext().getSizeType();
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000504 SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
505 MR, Ex, sizeTy, Count);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000506 state = state->set<CStringLength>(MR, strLength);
507 return strLength;
Jordy Rosea5261542010-08-14 21:02:52 +0000508}
509
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000510SVal CStringChecker::getCStringLength(CheckerContext &C, const GRState *&state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000511 const Expr *Ex, SVal Buf) const {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000512 const MemRegion *MR = Buf.getAsRegion();
513 if (!MR) {
514 // If we can't get a region, see if it's something we /know/ isn't a
515 // C string. In the context of locations, the only time we can issue such
516 // a warning is for labels.
517 if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000518 if (ExplodedNode *N = C.generateNode(state)) {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000519 if (!BT_NotCString)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000520 BT_NotCString.reset(new BuiltinBug("API",
521 "Argument is not a null-terminated string."));
Jordy Rose19c5dd12010-07-27 01:37:31 +0000522
523 llvm::SmallString<120> buf;
524 llvm::raw_svector_ostream os(buf);
525 os << "Argument to byte string function is the address of the label '"
Chris Lattner68106302011-02-17 05:38:27 +0000526 << Label->getLabel()->getName()
Jordy Rose19c5dd12010-07-27 01:37:31 +0000527 << "', which is not a null-terminated string";
528
529 // Generate a report for this bug.
530 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
531 os.str(), N);
532
533 report->addRange(Ex->getSourceRange());
534 C.EmitReport(report);
535 }
536
537 return UndefinedVal();
538 }
539
Jordy Rosea5261542010-08-14 21:02:52 +0000540 // If it's not a region and not a label, give up.
541 return UnknownVal();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000542 }
543
Jordy Rosea5261542010-08-14 21:02:52 +0000544 // If we have a region, strip casts from it and see if we can figure out
545 // its length. For anything we can't figure out, just return UnknownVal.
546 MR = MR->StripCasts();
547
548 switch (MR->getKind()) {
549 case MemRegion::StringRegionKind: {
550 // Modifying the contents of string regions is undefined [C99 6.4.5p6],
551 // so we can assume that the byte length is the correct C string length.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000552 SValBuilder &svalBuilder = C.getSValBuilder();
553 QualType sizeTy = svalBuilder.getContext().getSizeType();
554 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
555 return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
Jordy Rosea5261542010-08-14 21:02:52 +0000556 }
557 case MemRegion::SymbolicRegionKind:
558 case MemRegion::AllocaRegionKind:
559 case MemRegion::VarRegionKind:
560 case MemRegion::FieldRegionKind:
561 case MemRegion::ObjCIvarRegionKind:
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000562 return getCStringLengthForRegion(C, state, Ex, MR);
Jordy Rosea5261542010-08-14 21:02:52 +0000563 case MemRegion::CompoundLiteralRegionKind:
564 // FIXME: Can we track this? Is it necessary?
565 return UnknownVal();
566 case MemRegion::ElementRegionKind:
567 // FIXME: How can we handle this? It's not good enough to subtract the
568 // offset from the base string length; consider "123\x00567" and &a[5].
569 return UnknownVal();
570 default:
571 // Other regions (mostly non-data) can't have a reliable C string length.
572 // In this case, an error is emitted and UndefinedVal is returned.
573 // The caller should always be prepared to handle this case.
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000574 if (ExplodedNode *N = C.generateNode(state)) {
Jordy Rosea5261542010-08-14 21:02:52 +0000575 if (!BT_NotCString)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000576 BT_NotCString.reset(new BuiltinBug("API",
577 "Argument is not a null-terminated string."));
Jordy Rosea5261542010-08-14 21:02:52 +0000578
579 llvm::SmallString<120> buf;
580 llvm::raw_svector_ostream os(buf);
581
582 os << "Argument to byte string function is ";
583
584 if (SummarizeRegion(os, C.getASTContext(), MR))
585 os << ", which is not a null-terminated string";
586 else
587 os << "not a null-terminated string";
588
589 // Generate a report for this bug.
590 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
591 os.str(), N);
592
593 report->addRange(Ex->getSourceRange());
594 C.EmitReport(report);
595 }
596
597 return UndefinedVal();
598 }
Jordy Rose19c5dd12010-07-27 01:37:31 +0000599}
600
Lenny Maiorani318dd922011-04-12 17:08:43 +0000601const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
602 const GRState *&state, const Expr *expr, SVal val) const {
603
604 // Get the memory region pointed to by the val.
605 const MemRegion *bufRegion = val.getAsRegion();
606 if (!bufRegion)
607 return NULL;
608
609 // Strip casts off the memory region.
610 bufRegion = bufRegion->StripCasts();
611
612 // Cast the memory region to a string region.
613 const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
614 if (!strRegion)
615 return NULL;
616
617 // Return the actual string in the string region.
618 return strRegion->getStringLiteral();
619}
620
Jordy Rosee64f3112010-08-16 07:51:42 +0000621const GRState *CStringChecker::InvalidateBuffer(CheckerContext &C,
622 const GRState *state,
623 const Expr *E, SVal V) {
624 Loc *L = dyn_cast<Loc>(&V);
625 if (!L)
626 return state;
627
628 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
629 // some assumptions about the value that CFRefCount can't. Even so, it should
630 // probably be refactored.
631 if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
632 const MemRegion *R = MR->getRegion()->StripCasts();
633
634 // Are we dealing with an ElementRegion? If so, we should be invalidating
635 // the super-region.
636 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
637 R = ER->getSuperRegion();
638 // FIXME: What about layers of ElementRegions?
639 }
640
641 // Invalidate this region.
642 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenek25345282011-02-11 19:48:15 +0000643 return state->invalidateRegion(R, E, Count, NULL);
Jordy Rosee64f3112010-08-16 07:51:42 +0000644 }
645
646 // If we have a non-region value by chance, just remove the binding.
647 // FIXME: is this necessary or correct? This handles the non-Region
648 // cases. Is it ever valid to store to these?
649 return state->unbindLoc(*L);
650}
651
Jordy Rose19c5dd12010-07-27 01:37:31 +0000652bool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
653 const MemRegion *MR) {
654 const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
655 if (!TR)
656 return false;
657
658 switch (TR->getKind()) {
659 case MemRegion::FunctionTextRegionKind: {
660 const FunctionDecl *FD = cast<FunctionTextRegion>(TR)->getDecl();
661 if (FD)
662 os << "the address of the function '" << FD << "'";
663 else
664 os << "the address of a function";
665 return true;
666 }
667 case MemRegion::BlockTextRegionKind:
668 os << "block text";
669 return true;
670 case MemRegion::BlockDataRegionKind:
671 os << "a block";
672 return true;
673 case MemRegion::CXXThisRegionKind:
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000674 case MemRegion::CXXTempObjectRegionKind:
675 os << "a C++ temp object of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000676 return true;
677 case MemRegion::VarRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000678 os << "a variable of type" << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000679 return true;
680 case MemRegion::FieldRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000681 os << "a field of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000682 return true;
683 case MemRegion::ObjCIvarRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000684 os << "an instance variable of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000685 return true;
686 default:
687 return false;
688 }
689}
690
Jordy Rosed325ffb2010-07-08 23:57:29 +0000691//===----------------------------------------------------------------------===//
Ted Kremenek9c149532010-12-01 21:57:22 +0000692// evaluation of individual function calls.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000693//===----------------------------------------------------------------------===//
694
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000695void CStringChecker::evalCopyCommon(CheckerContext &C,
696 const CallExpr *CE,
697 const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000698 const Expr *Size, const Expr *Dest,
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000699 const Expr *Source, bool Restricted,
700 bool IsMempcpy) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000701 // See if the size argument is zero.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000702 SVal sizeVal = state->getSVal(Size);
703 QualType sizeTy = Size->getType();
Jordy Rosed325ffb2010-07-08 23:57:29 +0000704
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000705 const GRState *stateZeroSize, *stateNonZeroSize;
706 llvm::tie(stateZeroSize, stateNonZeroSize) = assumeZero(C, state, sizeVal, sizeTy);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000707
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000708 // Get the value of the Dest.
709 SVal destVal = state->getSVal(Dest);
710
711 // If the size is zero, there won't be any actual memory access, so
712 // just bind the return value to the destination buffer and return.
713 if (stateZeroSize) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000714 C.addTransition(stateZeroSize);
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000715 if (IsMempcpy)
716 state->BindExpr(CE, destVal);
717 else
718 state->BindExpr(CE, sizeVal);
719 return;
720 }
Jordy Rosed325ffb2010-07-08 23:57:29 +0000721
722 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000723 if (stateNonZeroSize) {
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000724
725 // Ensure the destination is not null. If it is NULL there will be a
726 // NULL pointer dereference.
727 state = checkNonNull(C, state, Dest, destVal);
728 if (!state)
729 return;
730
731 // Get the value of the Src.
732 SVal srcVal = state->getSVal(Source);
733
734 // Ensure the source is not null. If it is NULL there will be a
735 // NULL pointer dereference.
736 state = checkNonNull(C, state, Source, srcVal);
737 if (!state)
738 return;
739
740 // Ensure the buffers do not overlap.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000741 state = stateNonZeroSize;
Jordy Rosee64f3112010-08-16 07:51:42 +0000742 state = CheckBufferAccess(C, state, Size, Dest, Source,
743 /* FirstIsDst = */ true);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000744 if (Restricted)
745 state = CheckOverlap(C, state, Size, Dest, Source);
Jordy Rosee64f3112010-08-16 07:51:42 +0000746
747 if (state) {
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000748
749 // If this is mempcpy, get the byte after the last byte copied and
750 // bind the expr.
751 if (IsMempcpy) {
752 loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
753
754 // Get the length to copy.
755 SVal lenVal = state->getSVal(Size);
756 NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&lenVal);
757
758 // Get the byte after the last byte copied.
759 SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
760 *destRegVal,
761 *lenValNonLoc,
762 Dest->getType());
763
764 // The byte after the last byte copied is the return value.
765 state = state->BindExpr(CE, lastElement);
766 }
767
Jordy Rosee64f3112010-08-16 07:51:42 +0000768 // Invalidate the destination.
769 // FIXME: Even if we can't perfectly model the copy, we should see if we
770 // can use LazyCompoundVals to copy the source values into the destination.
771 // This would probably remove any existing bindings past the end of the
772 // copied region, but that's still an improvement over blank invalidation.
773 state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000774 C.addTransition(state);
Jordy Rosee64f3112010-08-16 07:51:42 +0000775 }
Jordy Rosed325ffb2010-07-08 23:57:29 +0000776 }
777}
778
779
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000780void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000781 // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000782 // The return value is the address of the destination buffer.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000783 const Expr *Dest = CE->getArg(0);
784 const GRState *state = C.getState();
785 state = state->BindExpr(CE, state->getSVal(Dest));
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000786 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
787}
788
789void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
790 // void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
791 // The return value is a pointer to the byte following the last written byte.
792 const Expr *Dest = CE->getArg(0);
793 const GRState *state = C.getState();
794
795 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000796}
797
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000798void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000799 // void *memmove(void *dst, const void *src, size_t n);
800 // The return value is the address of the destination buffer.
801 const Expr *Dest = CE->getArg(0);
802 const GRState *state = C.getState();
803 state = state->BindExpr(CE, state->getSVal(Dest));
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000804 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000805}
806
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000807void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000808 // void bcopy(const void *src, void *dst, size_t n);
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000809 evalCopyCommon(C, CE, C.getState(),
810 CE->getArg(2), CE->getArg(1), CE->getArg(0));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000811}
812
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000813void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000814 // int memcmp(const void *s1, const void *s2, size_t n);
815 const Expr *Left = CE->getArg(0);
816 const Expr *Right = CE->getArg(1);
817 const Expr *Size = CE->getArg(2);
818
819 const GRState *state = C.getState();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000820 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000821
Jordy Rosed325ffb2010-07-08 23:57:29 +0000822 // See if the size argument is zero.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000823 SVal sizeVal = state->getSVal(Size);
824 QualType sizeTy = Size->getType();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000825
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000826 const GRState *stateZeroSize, *stateNonZeroSize;
827 llvm::tie(stateZeroSize, stateNonZeroSize) =
828 assumeZero(C, state, sizeVal, sizeTy);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000829
Jordy Rosed325ffb2010-07-08 23:57:29 +0000830 // If the size can be zero, the result will be 0 in that case, and we don't
831 // have to check either of the buffers.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000832 if (stateZeroSize) {
833 state = stateZeroSize;
834 state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000835 C.addTransition(state);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000836 }
837
Jordy Rosed325ffb2010-07-08 23:57:29 +0000838 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000839 if (stateNonZeroSize) {
840 state = stateNonZeroSize;
Jordy Rosed325ffb2010-07-08 23:57:29 +0000841 // If we know the two buffers are the same, we know the result is 0.
842 // First, get the two buffers' addresses. Another checker will have already
843 // made sure they're not undefined.
844 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
845 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000846
Jordy Rosed325ffb2010-07-08 23:57:29 +0000847 // See if they are the same.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000848 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000849 const GRState *StSameBuf, *StNotSameBuf;
Ted Kremenek28f47b92010-12-01 22:16:56 +0000850 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000851
852 // If the two arguments might be the same buffer, we know the result is zero,
853 // and we only need to check one size.
854 if (StSameBuf) {
855 state = StSameBuf;
856 state = CheckBufferAccess(C, state, Size, Left);
857 if (state) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000858 state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000859 C.addTransition(state);
860 }
861 }
862
863 // If the two arguments might be different buffers, we have to check the
864 // size of both of them.
865 if (StNotSameBuf) {
866 state = StNotSameBuf;
867 state = CheckBufferAccess(C, state, Size, Left, Right);
868 if (state) {
869 // The return value is the comparison result, which we don't know.
870 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000871 SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000872 state = state->BindExpr(CE, CmpV);
873 C.addTransition(state);
874 }
875 }
876 }
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000877}
878
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000879void CStringChecker::evalstrLength(CheckerContext &C,
880 const CallExpr *CE) const {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000881 // size_t strlen(const char *s);
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000882 evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
883}
884
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000885void CStringChecker::evalstrnLength(CheckerContext &C,
886 const CallExpr *CE) const {
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000887 // size_t strnlen(const char *s, size_t maxlen);
888 evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
889}
890
891void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000892 bool IsStrnlen) const {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000893 const GRState *state = C.getState();
894 const Expr *Arg = CE->getArg(0);
895 SVal ArgVal = state->getSVal(Arg);
896
897 // Check that the argument is non-null.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000898 state = checkNonNull(C, state, Arg, ArgVal);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000899
900 if (state) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000901 SVal strLength = getCStringLength(C, state, Arg, ArgVal);
Jordy Rosea5261542010-08-14 21:02:52 +0000902
903 // If the argument isn't a valid C string, there's no valid state to
904 // transition to.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000905 if (strLength.isUndef())
Jordy Rosea5261542010-08-14 21:02:52 +0000906 return;
907
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000908 // If the check is for strnlen() then bind the return value to no more than
909 // the maxlen value.
910 if (IsStrnlen) {
911 const Expr *maxlenExpr = CE->getArg(1);
912 SVal maxlenVal = state->getSVal(maxlenExpr);
913
914 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
915 NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
916
917 QualType cmpTy = C.getSValBuilder().getContext().IntTy;
918 const GRState *stateTrue, *stateFalse;
919
920 // Check if the strLength is greater than or equal to the maxlen
921 llvm::tie(stateTrue, stateFalse) =
922 state->assume(cast<DefinedOrUnknownSVal>
923 (C.getSValBuilder().evalBinOpNN(state, BO_GE,
924 *strLengthNL, *maxlenValNL,
925 cmpTy)));
926
927 // If the strLength is greater than or equal to the maxlen, set strLength
928 // to maxlen
929 if (stateTrue && !stateFalse) {
930 strLength = maxlenVal;
931 }
932 }
933
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000934 // If getCStringLength couldn't figure out the length, conjure a return
Jordy Rosea5261542010-08-14 21:02:52 +0000935 // value, so it can be used in constraints, at least.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000936 if (strLength.isUnknown()) {
Jordy Rosea5261542010-08-14 21:02:52 +0000937 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000938 strLength = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000939 }
Jordy Rosea5261542010-08-14 21:02:52 +0000940
941 // Bind the return value.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000942 state = state->BindExpr(CE, strLength);
Jordy Rosea5261542010-08-14 21:02:52 +0000943 C.addTransition(state);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000944 }
945}
946
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000947void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosee64f3112010-08-16 07:51:42 +0000948 // char *strcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000949 evalStrcpyCommon(C, CE,
950 /* returnEnd = */ false,
951 /* isBounded = */ false,
952 /* isAppending = */ false);
Ted Kremenek0ef473f2011-02-22 04:58:34 +0000953}
954
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000955void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
Ted Kremenek0ef473f2011-02-22 04:58:34 +0000956 // char *strcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000957 evalStrcpyCommon(C, CE,
958 /* returnEnd = */ false,
959 /* isBounded = */ true,
960 /* isAppending = */ false);
Jordy Rosee64f3112010-08-16 07:51:42 +0000961}
962
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000963void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosee64f3112010-08-16 07:51:42 +0000964 // char *stpcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000965 evalStrcpyCommon(C, CE,
966 /* returnEnd = */ true,
967 /* isBounded = */ false,
968 /* isAppending = */ false);
969}
970
971void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
972 //char *strcat(char *restrict s1, const char *restrict s2);
973 evalStrcpyCommon(C, CE,
974 /* returnEnd = */ false,
975 /* isBounded = */ false,
976 /* isAppending = */ true);
977}
978
979void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
980 //char *strncat(char *restrict s1, const char *restrict s2, size_t n);
981 evalStrcpyCommon(C, CE,
982 /* returnEnd = */ false,
983 /* isBounded = */ true,
984 /* isAppending = */ true);
Jordy Rosee64f3112010-08-16 07:51:42 +0000985}
986
Ted Kremenek9c149532010-12-01 21:57:22 +0000987void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000988 bool returnEnd, bool isBounded,
989 bool isAppending) const {
Jordy Rosee64f3112010-08-16 07:51:42 +0000990 const GRState *state = C.getState();
991
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000992 // Check that the destination is non-null.
Jordy Rosee64f3112010-08-16 07:51:42 +0000993 const Expr *Dst = CE->getArg(0);
994 SVal DstVal = state->getSVal(Dst);
995
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000996 state = checkNonNull(C, state, Dst, DstVal);
Jordy Rosee64f3112010-08-16 07:51:42 +0000997 if (!state)
998 return;
999
1000 // Check that the source is non-null.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001001 const Expr *srcExpr = CE->getArg(1);
1002 SVal srcVal = state->getSVal(srcExpr);
1003 state = checkNonNull(C, state, srcExpr, srcVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001004 if (!state)
1005 return;
1006
1007 // Get the string length of the source.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001008 SVal strLength = getCStringLength(C, state, srcExpr, srcVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001009
1010 // If the source isn't a valid C string, give up.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001011 if (strLength.isUndef())
Jordy Rosee64f3112010-08-16 07:51:42 +00001012 return;
1013
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001014 // If the function is strncpy, strncat, etc... it is bounded.
1015 if (isBounded) {
1016 // Get the max number of characters to copy.
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001017 const Expr *lenExpr = CE->getArg(2);
1018 SVal lenVal = state->getSVal(lenExpr);
1019
Lenny Maiorani508c6272011-04-28 18:59:43 +00001020 // Cast the length to a NonLoc SVal. If it is not a NonLoc then give up.
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001021 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
Lenny Maiorani508c6272011-04-28 18:59:43 +00001022 if (!strLengthNL)
1023 return;
1024
1025 // Cast the max length to a NonLoc SVal. If it is not a NonLoc then give up.
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001026 NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
Lenny Maiorani508c6272011-04-28 18:59:43 +00001027 if (!lenValNL)
1028 return;
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001029
1030 QualType cmpTy = C.getSValBuilder().getContext().IntTy;
1031 const GRState *stateTrue, *stateFalse;
1032
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001033 // Check if the max number to copy is less than the length of the src.
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001034 llvm::tie(stateTrue, stateFalse) =
1035 state->assume(cast<DefinedOrUnknownSVal>
1036 (C.getSValBuilder().evalBinOpNN(state, BO_GT,
1037 *strLengthNL, *lenValNL,
1038 cmpTy)));
1039
1040 if (stateTrue) {
1041 // Max number to copy is less than the length of the src, so the actual
1042 // strLength copied is the max number arg.
1043 strLength = lenVal;
1044 }
1045 }
1046
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001047 // If this is an appending function (strcat, strncat...) then set the
1048 // string length to strlen(src) + strlen(dst) since the buffer will
1049 // ultimately contain both.
1050 if (isAppending) {
1051 // Get the string length of the destination, or give up.
1052 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
1053 if (dstStrLength.isUndef())
1054 return;
1055
1056 NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&strLength);
1057 NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
1058
1059 // If src or dst cast to NonLoc is NULL, give up.
1060 if ((!srcStrLengthNL) || (!dstStrLengthNL))
1061 return;
1062
1063 QualType addTy = C.getSValBuilder().getContext().getSizeType();
1064
1065 strLength = C.getSValBuilder().evalBinOpNN(state, BO_Add,
1066 *srcStrLengthNL, *dstStrLengthNL,
1067 addTy);
1068 }
1069
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001070 SVal Result = (returnEnd ? UnknownVal() : DstVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001071
1072 // If the destination is a MemRegion, try to check for a buffer overflow and
1073 // record the new string length.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001074 if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
Jordy Rosee64f3112010-08-16 07:51:42 +00001075 // If the length is known, we can check for an overflow.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001076 if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&strLength)) {
1077 SVal lastElement =
1078 C.getSValBuilder().evalBinOpLN(state, BO_Add, *dstRegVal,
1079 *knownStrLength, Dst->getType());
Jordy Rosee64f3112010-08-16 07:51:42 +00001080
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001081 state = CheckLocation(C, state, Dst, lastElement, /* IsDst = */ true);
Jordy Rosee64f3112010-08-16 07:51:42 +00001082 if (!state)
1083 return;
1084
1085 // If this is a stpcpy-style copy, the last element is the return value.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001086 if (returnEnd)
1087 Result = lastElement;
Jordy Rosee64f3112010-08-16 07:51:42 +00001088 }
1089
1090 // Invalidate the destination. This must happen before we set the C string
1091 // length because invalidation will clear the length.
1092 // FIXME: Even if we can't perfectly model the copy, we should see if we
1093 // can use LazyCompoundVals to copy the source values into the destination.
1094 // This would probably remove any existing bindings past the end of the
1095 // string, but that's still an improvement over blank invalidation.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001096 state = InvalidateBuffer(C, state, Dst, *dstRegVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001097
1098 // Set the C string length of the destination.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001099 state = setCStringLength(state, dstRegVal->getRegion(), strLength);
Jordy Rosee64f3112010-08-16 07:51:42 +00001100 }
1101
1102 // If this is a stpcpy-style copy, but we were unable to check for a buffer
1103 // overflow, we still need a result. Conjure a return value.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001104 if (returnEnd && Result.isUnknown()) {
1105 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rosee64f3112010-08-16 07:51:42 +00001106 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001107 strLength = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rosee64f3112010-08-16 07:51:42 +00001108 }
1109
1110 // Set the return value.
1111 state = state->BindExpr(CE, Result);
1112 C.addTransition(state);
1113}
1114
Lenny Maiorani318dd922011-04-12 17:08:43 +00001115void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
1116 //int strcmp(const char *restrict s1, const char *restrict s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001117 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001118}
Lenny Maiorani318dd922011-04-12 17:08:43 +00001119
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001120void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
1121 //int strncmp(const char *restrict s1, const char *restrict s2, size_t n);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001122 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
1123}
1124
1125void CStringChecker::evalStrcasecmp(CheckerContext &C,
1126 const CallExpr *CE) const {
1127 //int strcasecmp(const char *restrict s1, const char *restrict s2);
1128 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001129}
1130
1131void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001132 bool isBounded, bool ignoreCase) const {
Lenny Maiorani318dd922011-04-12 17:08:43 +00001133 const GRState *state = C.getState();
1134
1135 // Check that the first string is non-null
1136 const Expr *s1 = CE->getArg(0);
1137 SVal s1Val = state->getSVal(s1);
1138 state = checkNonNull(C, state, s1, s1Val);
1139 if (!state)
1140 return;
1141
1142 // Check that the second string is non-null.
1143 const Expr *s2 = CE->getArg(1);
1144 SVal s2Val = state->getSVal(s2);
1145 state = checkNonNull(C, state, s2, s2Val);
1146 if (!state)
1147 return;
1148
1149 // Get the string length of the first string or give up.
1150 SVal s1Length = getCStringLength(C, state, s1, s1Val);
1151 if (s1Length.isUndef())
1152 return;
1153
1154 // Get the string length of the second string or give up.
1155 SVal s2Length = getCStringLength(C, state, s2, s2Val);
1156 if (s2Length.isUndef())
1157 return;
1158
1159 // Get the string literal of the first string.
1160 const StringLiteral *s1StrLiteral = getCStringLiteral(C, state, s1, s1Val);
1161 if (!s1StrLiteral)
1162 return;
1163 llvm::StringRef s1StrRef = s1StrLiteral->getString();
1164
1165 // Get the string literal of the second string.
1166 const StringLiteral *s2StrLiteral = getCStringLiteral(C, state, s2, s2Val);
1167 if (!s2StrLiteral)
1168 return;
1169 llvm::StringRef s2StrRef = s2StrLiteral->getString();
1170
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001171 int result;
1172 if (isBounded) {
1173 // Get the max number of characters to compare.
1174 const Expr *lenExpr = CE->getArg(2);
1175 SVal lenVal = state->getSVal(lenExpr);
1176
1177 // Dynamically cast the length to a ConcreteInt. If it is not a ConcreteInt
1178 // then give up, otherwise get the value and use it as the bounds.
1179 nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&lenVal);
1180 if (!CI)
1181 return;
1182 llvm::APSInt lenInt(CI->getValue());
1183
1184 // Compare using the bounds provided like strncmp() does.
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001185 if (ignoreCase) {
1186 // TODO Implement compare_lower(RHS, n) in LLVM StringRef.
1187 // result = s1StrRef.compare_lower(s2StrRef,
1188 // (size_t)lenInt.getLimitedValue());
1189
1190 // For now, give up.
1191 return;
1192 } else {
1193 result = s1StrRef.compare(s2StrRef, (size_t)lenInt.getLimitedValue());
1194 }
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001195 } else {
1196 // Compare string 1 to string 2 the same way strcmp() does.
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001197 if (ignoreCase) {
1198 result = s1StrRef.compare_lower(s2StrRef);
1199 } else {
1200 result = s1StrRef.compare(s2StrRef);
1201 }
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001202 }
Lenny Maiorani318dd922011-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 Rosed325ffb2010-07-08 23:57:29 +00001215//===----------------------------------------------------------------------===//
Jordy Rosea5261542010-08-14 21:02:52 +00001216// The driver method, and other Checker callbacks.
Jordy Rosed325ffb2010-07-08 23:57:29 +00001217//===----------------------------------------------------------------------===//
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001218
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001219bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
Jordy Roseccbf7ee2010-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 Gregor90d26a42010-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 Roseccbf7ee2010-07-06 23:11:01 +00001234 if (Name.startswith("__builtin_"))
1235 Name = Name.substr(10);
1236
Ted Kremenek9c149532010-12-01 21:57:22 +00001237 FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
1238 .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
Lenny Maioranib8b875b2011-03-31 21:36:53 +00001239 .Case("mempcpy", &CStringChecker::evalMempcpy)
Ted Kremenek9c149532010-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 Kremenek0ef473f2011-02-22 04:58:34 +00001243 .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
Ted Kremenek9c149532010-12-01 21:57:22 +00001244 .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001245 .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat)
1246 .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat)
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001247 .Case("strlen", &CStringChecker::evalstrLength)
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001248 .Case("strnlen", &CStringChecker::evalstrnLength)
Lenny Maiorani318dd922011-04-12 17:08:43 +00001249 .Case("strcmp", &CStringChecker::evalStrcmp)
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001250 .Case("strncmp", &CStringChecker::evalStrncmp)
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001251 .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
Ted Kremenek9c149532010-12-01 21:57:22 +00001252 .Case("bcopy", &CStringChecker::evalBcopy)
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001253 .Default(NULL);
1254
Jordy Rosed325ffb2010-07-08 23:57:29 +00001255 // If the callee isn't a string function, let another checker handle it.
Ted Kremenek9c149532010-12-01 21:57:22 +00001256 if (!evalFunction)
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001257 return false;
1258
Jordy Rosed325ffb2010-07-08 23:57:29 +00001259 // Check and evaluate the call.
Ted Kremenek9c149532010-12-01 21:57:22 +00001260 (this->*evalFunction)(C, CE);
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001261 return true;
1262}
Jordy Rosea5261542010-08-14 21:02:52 +00001263
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001264void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001265 // Record string length for char a[] = "abc";
1266 const GRState *state = C.getState();
1267
1268 for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
1269 I != E; ++I) {
1270 const VarDecl *D = dyn_cast<VarDecl>(*I);
1271 if (!D)
1272 continue;
1273
1274 // FIXME: Handle array fields of structs.
1275 if (!D->getType()->isArrayType())
1276 continue;
1277
1278 const Expr *Init = D->getInit();
1279 if (!Init)
1280 continue;
1281 if (!isa<StringLiteral>(Init))
1282 continue;
1283
1284 Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
1285 const MemRegion *MR = VarLoc.getAsRegion();
1286 if (!MR)
1287 continue;
1288
1289 SVal StrVal = state->getSVal(Init);
1290 assert(StrVal.isValid() && "Initializer string is unknown or undefined");
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001291 DefinedOrUnknownSVal strLength
1292 = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
Jordy Rosea5261542010-08-14 21:02:52 +00001293
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001294 state = state->set<CStringLength>(MR, strLength);
Jordy Rosea5261542010-08-14 21:02:52 +00001295 }
1296
1297 C.addTransition(state);
1298}
1299
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001300bool CStringChecker::wantsRegionChangeUpdate(const GRState *state) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001301 CStringLength::EntryMap Entries = state->get<CStringLength>();
1302 return !Entries.isEmpty();
1303}
1304
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001305const GRState *
1306CStringChecker::checkRegionChanges(const GRState *state,
1307 const MemRegion * const *Begin,
1308 const MemRegion * const *End) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001309 CStringLength::EntryMap Entries = state->get<CStringLength>();
1310 if (Entries.isEmpty())
1311 return state;
1312
1313 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
1314 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
1315
1316 // First build sets for the changed regions and their super-regions.
1317 for ( ; Begin != End; ++Begin) {
1318 const MemRegion *MR = *Begin;
1319 Invalidated.insert(MR);
1320
1321 SuperRegions.insert(MR);
1322 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
1323 MR = SR->getSuperRegion();
1324 SuperRegions.insert(MR);
1325 }
1326 }
1327
1328 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1329
1330 // Then loop over the entries in the current state.
1331 for (CStringLength::EntryMap::iterator I = Entries.begin(),
1332 E = Entries.end(); I != E; ++I) {
1333 const MemRegion *MR = I.getKey();
1334
1335 // Is this entry for a super-region of a changed region?
1336 if (SuperRegions.count(MR)) {
Ted Kremenek3baf6722010-11-24 00:54:37 +00001337 Entries = F.remove(Entries, MR);
Jordy Rosea5261542010-08-14 21:02:52 +00001338 continue;
1339 }
1340
1341 // Is this entry for a sub-region of a changed region?
1342 const MemRegion *Super = MR;
1343 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
1344 Super = SR->getSuperRegion();
1345 if (Invalidated.count(Super)) {
Ted Kremenek3baf6722010-11-24 00:54:37 +00001346 Entries = F.remove(Entries, MR);
Jordy Rosea5261542010-08-14 21:02:52 +00001347 break;
1348 }
1349 }
1350 }
1351
1352 return state->set<CStringLength>(Entries);
1353}
1354
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001355void CStringChecker::checkLiveSymbols(const GRState *state,
1356 SymbolReaper &SR) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001357 // Mark all symbols in our string length map as valid.
1358 CStringLength::EntryMap Entries = state->get<CStringLength>();
1359
1360 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1361 I != E; ++I) {
1362 SVal Len = I.getData();
1363 if (SymbolRef Sym = Len.getAsSymbol())
1364 SR.markInUse(Sym);
1365 }
1366}
1367
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001368void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
1369 CheckerContext &C) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001370 if (!SR.hasDeadSymbols())
1371 return;
1372
1373 const GRState *state = C.getState();
1374 CStringLength::EntryMap Entries = state->get<CStringLength>();
1375 if (Entries.isEmpty())
1376 return;
1377
1378 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1379 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1380 I != E; ++I) {
1381 SVal Len = I.getData();
1382 if (SymbolRef Sym = Len.getAsSymbol()) {
1383 if (SR.isDead(Sym))
Ted Kremenek3baf6722010-11-24 00:54:37 +00001384 Entries = F.remove(Entries, I.getKey());
Jordy Rosea5261542010-08-14 21:02:52 +00001385 }
1386 }
1387
1388 state = state->set<CStringLength>(Entries);
Ted Kremenekd048c6e2010-12-20 21:19:09 +00001389 C.generateNode(state);
Jordy Rosea5261542010-08-14 21:02:52 +00001390}
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001391
1392void ento::registerCStringChecker(CheckerManager &mgr) {
1393 mgr.registerChecker<CStringChecker>();
1394}