blob: 49d8bf5388be53fad22525b364ecef4264061da0 [file] [log] [blame]
Anna Zaksc800f682011-10-11 16:49:54 +00001//= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-//
Jordy Roseccbf7ee2010-07-06 23:11:01 +00002//
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 Kremenek18c66fd2011-08-15 22:09:50 +000020#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.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 > {
Jordy Rose9e49d9f2011-06-20 02:06:40 +000033 mutable llvm::OwningPtr<BugType> BT_Null, BT_Bounds,
Jordy Rosed5af0e12011-06-15 05:52:56 +000034 BT_Overlap, BT_NotCString,
35 BT_AdditionOverflow;
Jordy Rose9e49d9f2011-06-20 02:06:40 +000036 mutable const char *CurrentFunctionDescription;
37
Jordy Roseccbf7ee2010-07-06 23:11:01 +000038public:
Jordy Roseccbf7ee2010-07-06 23:11:01 +000039 static void *getTag() { static int tag; return &tag; }
40
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000041 bool evalCall(const CallExpr *CE, CheckerContext &C) const;
42 void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
Ted Kremenek18c66fd2011-08-15 22:09:50 +000043 void checkLiveSymbols(const ProgramState *state, SymbolReaper &SR) const;
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000044 void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
Ted Kremenek18c66fd2011-08-15 22:09:50 +000045 bool wantsRegionChangeUpdate(const ProgramState *state) const;
Jordy Rosea5261542010-08-14 21:02:52 +000046
Ted Kremenek18c66fd2011-08-15 22:09:50 +000047 const ProgramState *
48 checkRegionChanges(const ProgramState *state,
49 const StoreManager::InvalidatedSymbols *,
Jordy Rose537716a2011-08-27 22:51:26 +000050 ArrayRef<const MemRegion *> ExplicitRegions,
51 ArrayRef<const MemRegion *> Regions) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000052
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000053 typedef void (CStringChecker::*FnCheck)(CheckerContext &,
54 const CallExpr *) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000055
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000056 void evalMemcpy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranib8b875b2011-03-31 21:36:53 +000057 void evalMempcpy(CheckerContext &C, const CallExpr *CE) const;
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000058 void evalMemmove(CheckerContext &C, const CallExpr *CE) const;
59 void evalBcopy(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranib8b875b2011-03-31 21:36:53 +000060 void evalCopyCommon(CheckerContext &C, const CallExpr *CE,
Ted Kremenek18c66fd2011-08-15 22:09:50 +000061 const ProgramState *state,
62 const Expr *Size,
63 const Expr *Source,
64 const Expr *Dest,
Lenny Maioranib8b875b2011-03-31 21:36:53 +000065 bool Restricted = false,
66 bool IsMempcpy = false) const;
Jordy Rosed325ffb2010-07-08 23:57:29 +000067
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000068 void evalMemcmp(CheckerContext &C, const CallExpr *CE) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000069
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000070 void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
71 void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenek18c66fd2011-08-15 22:09:50 +000072 void evalstrLengthCommon(CheckerContext &C,
73 const CallExpr *CE,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000074 bool IsStrnlen = false) const;
Jordy Rose19c5dd12010-07-27 01:37:31 +000075
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000076 void evalStrcpy(CheckerContext &C, const CallExpr *CE) const;
77 void evalStrncpy(CheckerContext &C, const CallExpr *CE) const;
78 void evalStpcpy(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenek18c66fd2011-08-15 22:09:50 +000079 void evalStrcpyCommon(CheckerContext &C,
80 const CallExpr *CE,
81 bool returnEnd,
82 bool isBounded,
83 bool isAppending) const;
Lenny Maiorani067bbd02011-04-09 15:12:58 +000084
85 void evalStrcat(CheckerContext &C, const CallExpr *CE) const;
86 void evalStrncat(CheckerContext &C, const CallExpr *CE) const;
Jordy Rosee64f3112010-08-16 07:51:42 +000087
Lenny Maiorani318dd922011-04-12 17:08:43 +000088 void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani357f6ee2011-04-25 22:21:00 +000089 void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maioranibd1d16a2011-04-28 15:09:11 +000090 void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
Lenny Maiorani454fd2d2011-05-02 19:05:49 +000091 void evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const;
Ted Kremenek18c66fd2011-08-15 22:09:50 +000092 void evalStrcmpCommon(CheckerContext &C,
93 const CallExpr *CE,
94 bool isBounded = false,
95 bool ignoreCase = false) const;
Lenny Maiorani318dd922011-04-12 17:08:43 +000096
Jordy Roseccbf7ee2010-07-06 23:11:01 +000097 // Utility methods
Ted Kremenek18c66fd2011-08-15 22:09:50 +000098 std::pair<const ProgramState*, const ProgramState*>
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +000099 static assumeZero(CheckerContext &C,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000100 const ProgramState *state, SVal V, QualType Ty);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000101
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000102 static const ProgramState *setCStringLength(const ProgramState *state,
103 const MemRegion *MR,
104 SVal strLength);
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000105 static SVal getCStringLengthForRegion(CheckerContext &C,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000106 const ProgramState *&state,
107 const Expr *Ex,
108 const MemRegion *MR,
Jordy Rosed5af0e12011-06-15 05:52:56 +0000109 bool hypothetical);
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000110 SVal getCStringLength(CheckerContext &C,
111 const ProgramState *&state,
112 const Expr *Ex,
113 SVal Buf,
Jordy Rosed5af0e12011-06-15 05:52:56 +0000114 bool hypothetical = false) const;
Jordy Rose19c5dd12010-07-27 01:37:31 +0000115
Lenny Maiorani318dd922011-04-12 17:08:43 +0000116 const StringLiteral *getCStringLiteral(CheckerContext &C,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000117 const ProgramState *&state,
Lenny Maiorani318dd922011-04-12 17:08:43 +0000118 const Expr *expr,
119 SVal val) const;
120
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000121 static const ProgramState *InvalidateBuffer(CheckerContext &C,
122 const ProgramState *state,
123 const Expr *Ex, SVal V);
Jordy Rosee64f3112010-08-16 07:51:42 +0000124
Ted Kremenek9c378f72011-08-12 23:37:29 +0000125 static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000126 const MemRegion *MR);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000127
128 // Re-usable checks
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000129 const ProgramState *checkNonNull(CheckerContext &C,
130 const ProgramState *state,
131 const Expr *S,
132 SVal l) const;
133 const ProgramState *CheckLocation(CheckerContext &C,
134 const ProgramState *state,
135 const Expr *S,
136 SVal l,
137 const char *message = NULL) const;
138 const ProgramState *CheckBufferAccess(CheckerContext &C,
139 const ProgramState *state,
140 const Expr *Size,
141 const Expr *FirstBuf,
142 const Expr *SecondBuf,
143 const char *firstMessage = NULL,
144 const char *secondMessage = NULL,
145 bool WarnAboutSize = false) const;
146
147 const ProgramState *CheckBufferAccess(CheckerContext &C,
148 const ProgramState *state,
149 const Expr *Size,
150 const Expr *Buf,
151 const char *message = NULL,
152 bool WarnAboutSize = false) const {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000153 // This is a convenience override.
Jordy Rose5e5f1502011-06-20 03:49:16 +0000154 return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
155 WarnAboutSize);
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000156 }
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000157 const ProgramState *CheckOverlap(CheckerContext &C,
158 const ProgramState *state,
159 const Expr *Size,
160 const Expr *First,
161 const Expr *Second) const;
162 void emitOverlapBug(CheckerContext &C,
163 const ProgramState *state,
164 const Stmt *First,
165 const Stmt *Second) const;
166
167 const ProgramState *checkAdditionOverflow(CheckerContext &C,
168 const ProgramState *state,
169 NonLoc left,
170 NonLoc right) const;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000171};
Jordy Rosea5261542010-08-14 21:02:52 +0000172
173class CStringLength {
174public:
175 typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
176};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000177} //end anonymous namespace
178
Jordy Rosea5261542010-08-14 21:02:52 +0000179namespace clang {
Ted Kremenek9ef65372010-12-23 07:20:52 +0000180namespace ento {
Jordy Rosea5261542010-08-14 21:02:52 +0000181 template <>
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000182 struct ProgramStateTrait<CStringLength>
183 : public ProgramStatePartialTrait<CStringLength::EntryMap> {
Jordy Rosea5261542010-08-14 21:02:52 +0000184 static void *GDMIndex() { return CStringChecker::getTag(); }
185 };
186}
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +0000187}
Jordy Rosea5261542010-08-14 21:02:52 +0000188
Jordy Rosed325ffb2010-07-08 23:57:29 +0000189//===----------------------------------------------------------------------===//
190// Individual checks and utility methods.
191//===----------------------------------------------------------------------===//
192
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000193std::pair<const ProgramState*, const ProgramState*>
194CStringChecker::assumeZero(CheckerContext &C, const ProgramState *state, SVal V,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000195 QualType Ty) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000196 DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
197 if (!val)
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000198 return std::pair<const ProgramState*, const ProgramState *>(state, state);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000199
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000200 SValBuilder &svalBuilder = C.getSValBuilder();
201 DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty);
202 return state->assume(svalBuilder.evalEQ(state, *val, zero));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000203}
Jordy Rosea6b808c2010-07-07 07:48:06 +0000204
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000205const ProgramState *CStringChecker::checkNonNull(CheckerContext &C,
206 const ProgramState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000207 const Expr *S, SVal l) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000208 // If a previous check has failed, propagate the failure.
209 if (!state)
210 return NULL;
211
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000212 const ProgramState *stateNull, *stateNonNull;
Ted Kremenek28f47b92010-12-01 22:16:56 +0000213 llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
Jordy Rosed325ffb2010-07-08 23:57:29 +0000214
215 if (stateNull && !stateNonNull) {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000216 ExplodedNode *N = C.generateSink(stateNull);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000217 if (!N)
218 return NULL;
219
Jordy Rosed325ffb2010-07-08 23:57:29 +0000220 if (!BT_Null)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000221 BT_Null.reset(new BuiltinBug("API",
222 "Null pointer argument in call to byte string function"));
Jordy Rosea6b808c2010-07-07 07:48:06 +0000223
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000224 llvm::SmallString<80> buf;
225 llvm::raw_svector_ostream os(buf);
226 assert(CurrentFunctionDescription);
227 os << "Null pointer argument in call to " << CurrentFunctionDescription;
228
Jordy Rosea6b808c2010-07-07 07:48:06 +0000229 // Generate a report for this bug.
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000230 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null.get());
Anna Zakse172e8b2011-08-17 23:00:25 +0000231 BugReport *report = new BugReport(*BT, os.str(), N);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000232
233 report->addRange(S->getSourceRange());
Anna Zaks50bbc162011-08-19 22:33:38 +0000234 report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S));
Jordy Rosea6b808c2010-07-07 07:48:06 +0000235 C.EmitReport(report);
236 return NULL;
237 }
238
239 // From here on, assume that the value is non-null.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000240 assert(stateNonNull);
241 return stateNonNull;
Jordy Rosea6b808c2010-07-07 07:48:06 +0000242}
243
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000244// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000245const ProgramState *CStringChecker::CheckLocation(CheckerContext &C,
246 const ProgramState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000247 const Expr *S, SVal l,
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000248 const char *warningMsg) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000249 // If a previous check has failed, propagate the failure.
250 if (!state)
251 return NULL;
252
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000253 // Check for out of bound array element access.
254 const MemRegion *R = l.getAsRegion();
255 if (!R)
256 return state;
257
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000258 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
259 if (!ER)
260 return state;
261
Zhongxing Xu018220c2010-08-11 06:10:55 +0000262 assert(ER->getValueType() == C.getASTContext().CharTy &&
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000263 "CheckLocation should only be called with char* ElementRegions");
264
265 // Get the size of the array.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000266 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
267 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rose1e022412011-06-16 05:51:02 +0000268 SVal Extent =
269 svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000270 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
271
272 // Get the index of the accessed element.
Gabor Greif89b06582010-09-09 10:51:37 +0000273 DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000274
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000275 const ProgramState *StInBound = state->assumeInBound(Idx, Size, true);
276 const ProgramState *StOutBound = state->assumeInBound(Idx, Size, false);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000277 if (StOutBound && !StInBound) {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000278 ExplodedNode *N = C.generateSink(StOutBound);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000279 if (!N)
280 return NULL;
281
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000282 if (!BT_Bounds) {
283 BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
284 "Byte string function accesses out-of-bound array element"));
285 }
286 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get());
287
288 // Generate a report for this bug.
Anna Zakse172e8b2011-08-17 23:00:25 +0000289 BugReport *report;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000290 if (warningMsg) {
Anna Zakse172e8b2011-08-17 23:00:25 +0000291 report = new BugReport(*BT, warningMsg, N);
Jordy Rosee64f3112010-08-16 07:51:42 +0000292 } else {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000293 assert(CurrentFunctionDescription);
294 assert(CurrentFunctionDescription[0] != '\0');
295
296 llvm::SmallString<80> buf;
297 llvm::raw_svector_ostream os(buf);
298 os << (char)toupper(CurrentFunctionDescription[0])
299 << &CurrentFunctionDescription[1]
300 << " accesses out-of-bound array element";
Anna Zakse172e8b2011-08-17 23:00:25 +0000301 report = new BugReport(*BT, os.str(), N);
Jordy Rosee64f3112010-08-16 07:51:42 +0000302 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000303
304 // FIXME: It would be nice to eventually make this diagnostic more clear,
305 // e.g., by referencing the original declaration or by saying *why* this
306 // reference is outside the range.
307
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000308 report->addRange(S->getSourceRange());
309 C.EmitReport(report);
310 return NULL;
311 }
312
313 // Array bound check succeeded. From this point forward the array bound
314 // should always succeed.
315 return StInBound;
316}
317
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000318const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
319 const ProgramState *state,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000320 const Expr *Size,
321 const Expr *FirstBuf,
Jordy Rosee64f3112010-08-16 07:51:42 +0000322 const Expr *SecondBuf,
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000323 const char *firstMessage,
Jordy Rose5e5f1502011-06-20 03:49:16 +0000324 const char *secondMessage,
325 bool WarnAboutSize) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000326 // If a previous check has failed, propagate the failure.
327 if (!state)
328 return NULL;
329
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000330 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rose1e022412011-06-16 05:51:02 +0000331 ASTContext &Ctx = svalBuilder.getContext();
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000332
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000333 QualType sizeTy = Size->getType();
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000334 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
335
Jordy Rosea6b808c2010-07-07 07:48:06 +0000336 // Check that the first buffer is non-null.
337 SVal BufVal = state->getSVal(FirstBuf);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000338 state = checkNonNull(C, state, FirstBuf, BufVal);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000339 if (!state)
340 return NULL;
341
Jordy Rosed325ffb2010-07-08 23:57:29 +0000342 // Get the access length and make sure it is known.
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000343 // FIXME: This assumes the caller has already checked that the access length
344 // is positive. And that it's unsigned.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000345 SVal LengthVal = state->getSVal(Size);
346 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
347 if (!Length)
348 return state;
349
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000350 // Compute the offset of the last element to be accessed: size-1.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000351 NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
352 NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
353 *Length, One, sizeTy));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000354
Chris Lattnerfc8f0e12011-04-15 05:22:18 +0000355 // Check that the first buffer is sufficiently long.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000356 SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
Jordy Roseb6a40262010-08-05 23:11:30 +0000357 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Jordy Rose5e5f1502011-06-20 03:49:16 +0000358 const Expr *warningExpr = (WarnAboutSize ? Size : FirstBuf);
359
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000360 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
361 LastOffset, PtrTy);
Jordy Rose5e5f1502011-06-20 03:49:16 +0000362 state = CheckLocation(C, state, warningExpr, BufEnd, firstMessage);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000363
Jordy Roseb6a40262010-08-05 23:11:30 +0000364 // If the buffer isn't large enough, abort.
365 if (!state)
366 return NULL;
367 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000368
369 // If there's a second buffer, check it as well.
370 if (SecondBuf) {
371 BufVal = state->getSVal(SecondBuf);
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000372 state = checkNonNull(C, state, SecondBuf, BufVal);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000373 if (!state)
374 return NULL;
375
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000376 BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
Jordy Roseb6a40262010-08-05 23:11:30 +0000377 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
Jordy Rose5e5f1502011-06-20 03:49:16 +0000378 const Expr *warningExpr = (WarnAboutSize ? Size : SecondBuf);
379
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000380 SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
381 LastOffset, PtrTy);
Jordy Rose5e5f1502011-06-20 03:49:16 +0000382 state = CheckLocation(C, state, warningExpr, BufEnd, secondMessage);
Jordy Roseb6a40262010-08-05 23:11:30 +0000383 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000384 }
385
386 // Large enough or not, return this state!
387 return state;
388}
389
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000390const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
391 const ProgramState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000392 const Expr *Size,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000393 const Expr *First,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000394 const Expr *Second) const {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000395 // Do a simple check for overlap: if the two arguments are from the same
396 // buffer, see if the end of the first is greater than the start of the second
397 // or vice versa.
398
Jordy Rosed325ffb2010-07-08 23:57:29 +0000399 // If a previous check has failed, propagate the failure.
400 if (!state)
401 return NULL;
402
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000403 const ProgramState *stateTrue, *stateFalse;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000404
405 // Get the buffer values and make sure they're known locations.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000406 SVal firstVal = state->getSVal(First);
407 SVal secondVal = state->getSVal(Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000408
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000409 Loc *firstLoc = dyn_cast<Loc>(&firstVal);
410 if (!firstLoc)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000411 return state;
412
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000413 Loc *secondLoc = dyn_cast<Loc>(&secondVal);
414 if (!secondLoc)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000415 return state;
416
417 // Are the two values the same?
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000418 SValBuilder &svalBuilder = C.getSValBuilder();
419 llvm::tie(stateTrue, stateFalse) =
420 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000421
422 if (stateTrue && !stateFalse) {
423 // If the values are known to be equal, that's automatically an overlap.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000424 emitOverlapBug(C, stateTrue, First, Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000425 return NULL;
426 }
427
Ted Kremenek28f47b92010-12-01 22:16:56 +0000428 // assume the two expressions are not equal.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000429 assert(stateFalse);
430 state = stateFalse;
431
432 // Which value comes first?
Jordy Roseee2fde12011-06-16 05:56:50 +0000433 QualType cmpTy = svalBuilder.getConditionType();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000434 SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
435 *firstLoc, *secondLoc, cmpTy);
436 DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
437 if (!reverseTest)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000438 return state;
439
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000440 llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000441 if (stateTrue) {
442 if (stateFalse) {
443 // If we don't know which one comes first, we can't perform this test.
444 return state;
445 } else {
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000446 // Switch the values so that firstVal is before secondVal.
447 Loc *tmpLoc = firstLoc;
448 firstLoc = secondLoc;
449 secondLoc = tmpLoc;
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000450
451 // Switch the Exprs as well, so that they still correspond.
452 const Expr *tmpExpr = First;
453 First = Second;
454 Second = tmpExpr;
455 }
456 }
457
458 // Get the length, and make sure it too is known.
459 SVal LengthVal = state->getSVal(Size);
460 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
461 if (!Length)
462 return state;
463
464 // Convert the first buffer's start address to char*.
465 // Bail out if the cast fails.
Jordy Roseee2fde12011-06-16 05:56:50 +0000466 ASTContext &Ctx = svalBuilder.getContext();
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000467 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
Jordy Rose1e022412011-06-16 05:51:02 +0000468 SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy,
469 First->getType());
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000470 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
471 if (!FirstStartLoc)
472 return state;
473
474 // Compute the end of the first buffer. Bail out if THAT fails.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000475 SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000476 *FirstStartLoc, *Length, CharPtrTy);
477 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
478 if (!FirstEndLoc)
479 return state;
480
481 // Is the end of the first buffer past the start of the second buffer?
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000482 SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
483 *FirstEndLoc, *secondLoc, cmpTy);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000484 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
485 if (!OverlapTest)
486 return state;
487
Ted Kremenek28f47b92010-12-01 22:16:56 +0000488 llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000489
490 if (stateTrue && !stateFalse) {
491 // Overlap!
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000492 emitOverlapBug(C, stateTrue, First, Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000493 return NULL;
494 }
495
Ted Kremenek28f47b92010-12-01 22:16:56 +0000496 // assume the two expressions don't overlap.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000497 assert(stateFalse);
498 return stateFalse;
499}
500
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000501void CStringChecker::emitOverlapBug(CheckerContext &C, const ProgramState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000502 const Stmt *First, const Stmt *Second) const {
Ted Kremenekd048c6e2010-12-20 21:19:09 +0000503 ExplodedNode *N = C.generateSink(state);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000504 if (!N)
505 return;
506
507 if (!BT_Overlap)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000508 BT_Overlap.reset(new BugType("Unix API", "Improper arguments"));
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000509
510 // Generate a report for this bug.
Anna Zakse172e8b2011-08-17 23:00:25 +0000511 BugReport *report =
512 new BugReport(*BT_Overlap,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000513 "Arguments must not be overlapping buffers", N);
514 report->addRange(First->getSourceRange());
515 report->addRange(Second->getSourceRange());
516
517 C.EmitReport(report);
518}
519
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000520const ProgramState *CStringChecker::checkAdditionOverflow(CheckerContext &C,
521 const ProgramState *state,
Jordy Rosed5af0e12011-06-15 05:52:56 +0000522 NonLoc left,
523 NonLoc right) const {
524 // If a previous check has failed, propagate the failure.
525 if (!state)
526 return NULL;
527
528 SValBuilder &svalBuilder = C.getSValBuilder();
529 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
530
531 QualType sizeTy = svalBuilder.getContext().getSizeType();
532 const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
533 NonLoc maxVal = svalBuilder.makeIntVal(maxValInt);
534
Anna Zakse3d250e2011-12-11 18:43:40 +0000535 SVal maxMinusRight;
536 if (isa<nonloc::ConcreteInt>(right)) {
537 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right,
538 sizeTy);
539 } else {
Jordy Rosed5af0e12011-06-15 05:52:56 +0000540 // Try switching the operands. (The order of these two assignments is
541 // important!)
542 maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left,
543 sizeTy);
544 left = right;
545 }
546
547 if (NonLoc *maxMinusRightNL = dyn_cast<NonLoc>(&maxMinusRight)) {
548 QualType cmpTy = svalBuilder.getConditionType();
549 // If left > max - right, we have an overflow.
550 SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
551 *maxMinusRightNL, cmpTy);
552
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000553 const ProgramState *stateOverflow, *stateOkay;
Jordy Rosed5af0e12011-06-15 05:52:56 +0000554 llvm::tie(stateOverflow, stateOkay) =
555 state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
556
557 if (stateOverflow && !stateOkay) {
558 // We have an overflow. Emit a bug report.
559 ExplodedNode *N = C.generateSink(stateOverflow);
560 if (!N)
561 return NULL;
562
563 if (!BT_AdditionOverflow)
564 BT_AdditionOverflow.reset(new BuiltinBug("API",
565 "Sum of expressions causes overflow"));
566
Jordy Rosed5af0e12011-06-15 05:52:56 +0000567 // This isn't a great error message, but this should never occur in real
568 // code anyway -- you'd have to create a buffer longer than a size_t can
569 // represent, which is sort of a contradiction.
Jordy Rose8cc24912011-06-20 03:51:53 +0000570 const char *warning =
571 "This expression will create a string whose length is too big to "
572 "be represented as a size_t";
Jordy Rosed5af0e12011-06-15 05:52:56 +0000573
574 // Generate a report for this bug.
Jordy Rose8cc24912011-06-20 03:51:53 +0000575 BugReport *report = new BugReport(*BT_AdditionOverflow, warning, N);
Jordy Rosed5af0e12011-06-15 05:52:56 +0000576 C.EmitReport(report);
577
578 return NULL;
579 }
580
581 // From now on, assume an overflow didn't occur.
582 assert(stateOkay);
583 state = stateOkay;
584 }
585
586 return state;
587}
588
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000589const ProgramState *CStringChecker::setCStringLength(const ProgramState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000590 const MemRegion *MR,
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000591 SVal strLength) {
592 assert(!strLength.isUndef() && "Attempt to set an undefined string length");
Jordy Rosee64f3112010-08-16 07:51:42 +0000593
594 MR = MR->StripCasts();
595
596 switch (MR->getKind()) {
597 case MemRegion::StringRegionKind:
598 // FIXME: This can happen if we strcpy() into a string region. This is
599 // undefined [C99 6.4.5p6], but we should still warn about it.
600 return state;
601
602 case MemRegion::SymbolicRegionKind:
603 case MemRegion::AllocaRegionKind:
604 case MemRegion::VarRegionKind:
605 case MemRegion::FieldRegionKind:
606 case MemRegion::ObjCIvarRegionKind:
Jordy Rose210c05b2011-06-15 05:14:03 +0000607 // These are the types we can currently track string lengths for.
608 break;
Jordy Rosee64f3112010-08-16 07:51:42 +0000609
610 case MemRegion::ElementRegionKind:
611 // FIXME: Handle element regions by upper-bounding the parent region's
612 // string length.
613 return state;
614
615 default:
616 // Other regions (mostly non-data) can't have a reliable C string length.
617 // For now, just ignore the change.
618 // FIXME: These are rare but not impossible. We should output some kind of
619 // warning for things like strcpy((char[]){'a', 0}, "b");
620 return state;
621 }
Jordy Rose210c05b2011-06-15 05:14:03 +0000622
623 if (strLength.isUnknown())
624 return state->remove<CStringLength>(MR);
625
626 return state->set<CStringLength>(MR, strLength);
Jordy Rosee64f3112010-08-16 07:51:42 +0000627}
628
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000629SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000630 const ProgramState *&state,
Jordy Rosea5261542010-08-14 21:02:52 +0000631 const Expr *Ex,
Jordy Rosed5af0e12011-06-15 05:52:56 +0000632 const MemRegion *MR,
633 bool hypothetical) {
634 if (!hypothetical) {
635 // If there's a recorded length, go ahead and return it.
636 const SVal *Recorded = state->get<CStringLength>(MR);
637 if (Recorded)
638 return *Recorded;
639 }
Jordy Rosea5261542010-08-14 21:02:52 +0000640
641 // Otherwise, get a new symbol and update the state.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +0000642 unsigned Count = C.getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000643 SValBuilder &svalBuilder = C.getSValBuilder();
644 QualType sizeTy = svalBuilder.getContext().getSizeType();
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000645 SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(),
646 MR, Ex, sizeTy, Count);
Jordy Rosed5af0e12011-06-15 05:52:56 +0000647
648 if (!hypothetical)
649 state = state->set<CStringLength>(MR, strLength);
650
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000651 return strLength;
Jordy Rosea5261542010-08-14 21:02:52 +0000652}
653
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000654SVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&state,
Jordy Rosed5af0e12011-06-15 05:52:56 +0000655 const Expr *Ex, SVal Buf,
656 bool hypothetical) const {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000657 const MemRegion *MR = Buf.getAsRegion();
658 if (!MR) {
659 // If we can't get a region, see if it's something we /know/ isn't a
660 // C string. In the context of locations, the only time we can issue such
661 // a warning is for labels.
662 if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
Anna Zaks0bd6b112011-10-26 21:06:34 +0000663 if (ExplodedNode *N = C.addTransition(state)) {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000664 if (!BT_NotCString)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000665 BT_NotCString.reset(new BuiltinBug("API",
666 "Argument is not a null-terminated string."));
Jordy Rose19c5dd12010-07-27 01:37:31 +0000667
668 llvm::SmallString<120> buf;
669 llvm::raw_svector_ostream os(buf);
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000670 assert(CurrentFunctionDescription);
671 os << "Argument to " << CurrentFunctionDescription
672 << " is the address of the label '" << Label->getLabel()->getName()
Jordy Rose19c5dd12010-07-27 01:37:31 +0000673 << "', which is not a null-terminated string";
674
675 // Generate a report for this bug.
Anna Zakse172e8b2011-08-17 23:00:25 +0000676 BugReport *report = new BugReport(*BT_NotCString,
Jordy Rose19c5dd12010-07-27 01:37:31 +0000677 os.str(), N);
678
679 report->addRange(Ex->getSourceRange());
680 C.EmitReport(report);
681 }
682
683 return UndefinedVal();
684 }
685
Jordy Rosea5261542010-08-14 21:02:52 +0000686 // If it's not a region and not a label, give up.
687 return UnknownVal();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000688 }
689
Jordy Rosea5261542010-08-14 21:02:52 +0000690 // If we have a region, strip casts from it and see if we can figure out
691 // its length. For anything we can't figure out, just return UnknownVal.
692 MR = MR->StripCasts();
693
694 switch (MR->getKind()) {
695 case MemRegion::StringRegionKind: {
696 // Modifying the contents of string regions is undefined [C99 6.4.5p6],
697 // so we can assume that the byte length is the correct C string length.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000698 SValBuilder &svalBuilder = C.getSValBuilder();
699 QualType sizeTy = svalBuilder.getContext().getSizeType();
700 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
701 return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy);
Jordy Rosea5261542010-08-14 21:02:52 +0000702 }
703 case MemRegion::SymbolicRegionKind:
704 case MemRegion::AllocaRegionKind:
705 case MemRegion::VarRegionKind:
706 case MemRegion::FieldRegionKind:
707 case MemRegion::ObjCIvarRegionKind:
Jordy Rosed5af0e12011-06-15 05:52:56 +0000708 return getCStringLengthForRegion(C, state, Ex, MR, hypothetical);
Jordy Rosea5261542010-08-14 21:02:52 +0000709 case MemRegion::CompoundLiteralRegionKind:
710 // FIXME: Can we track this? Is it necessary?
711 return UnknownVal();
712 case MemRegion::ElementRegionKind:
713 // FIXME: How can we handle this? It's not good enough to subtract the
714 // offset from the base string length; consider "123\x00567" and &a[5].
715 return UnknownVal();
716 default:
717 // Other regions (mostly non-data) can't have a reliable C string length.
718 // In this case, an error is emitted and UndefinedVal is returned.
719 // The caller should always be prepared to handle this case.
Anna Zaks0bd6b112011-10-26 21:06:34 +0000720 if (ExplodedNode *N = C.addTransition(state)) {
Jordy Rosea5261542010-08-14 21:02:52 +0000721 if (!BT_NotCString)
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000722 BT_NotCString.reset(new BuiltinBug("API",
723 "Argument is not a null-terminated string."));
Jordy Rosea5261542010-08-14 21:02:52 +0000724
725 llvm::SmallString<120> buf;
726 llvm::raw_svector_ostream os(buf);
727
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000728 assert(CurrentFunctionDescription);
729 os << "Argument to " << CurrentFunctionDescription << " is ";
Jordy Rosea5261542010-08-14 21:02:52 +0000730
731 if (SummarizeRegion(os, C.getASTContext(), MR))
732 os << ", which is not a null-terminated string";
733 else
734 os << "not a null-terminated string";
735
736 // Generate a report for this bug.
Anna Zakse172e8b2011-08-17 23:00:25 +0000737 BugReport *report = new BugReport(*BT_NotCString,
Jordy Rosea5261542010-08-14 21:02:52 +0000738 os.str(), N);
739
740 report->addRange(Ex->getSourceRange());
741 C.EmitReport(report);
742 }
743
744 return UndefinedVal();
745 }
Jordy Rose19c5dd12010-07-27 01:37:31 +0000746}
747
Lenny Maiorani318dd922011-04-12 17:08:43 +0000748const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000749 const ProgramState *&state, const Expr *expr, SVal val) const {
Lenny Maiorani318dd922011-04-12 17:08:43 +0000750
751 // Get the memory region pointed to by the val.
752 const MemRegion *bufRegion = val.getAsRegion();
753 if (!bufRegion)
754 return NULL;
755
756 // Strip casts off the memory region.
757 bufRegion = bufRegion->StripCasts();
758
759 // Cast the memory region to a string region.
760 const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
761 if (!strRegion)
762 return NULL;
763
764 // Return the actual string in the string region.
765 return strRegion->getStringLiteral();
766}
767
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000768const ProgramState *CStringChecker::InvalidateBuffer(CheckerContext &C,
769 const ProgramState *state,
Jordy Rosee64f3112010-08-16 07:51:42 +0000770 const Expr *E, SVal V) {
771 Loc *L = dyn_cast<Loc>(&V);
772 if (!L)
773 return state;
774
775 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
776 // some assumptions about the value that CFRefCount can't. Even so, it should
777 // probably be refactored.
778 if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
779 const MemRegion *R = MR->getRegion()->StripCasts();
780
781 // Are we dealing with an ElementRegion? If so, we should be invalidating
782 // the super-region.
783 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
784 R = ER->getSuperRegion();
785 // FIXME: What about layers of ElementRegions?
786 }
787
788 // Invalidate this region.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +0000789 unsigned Count = C.getCurrentBlockCount();
Jordy Rose537716a2011-08-27 22:51:26 +0000790 return state->invalidateRegions(R, E, Count);
Jordy Rosee64f3112010-08-16 07:51:42 +0000791 }
792
793 // If we have a non-region value by chance, just remove the binding.
794 // FIXME: is this necessary or correct? This handles the non-Region
795 // cases. Is it ever valid to store to these?
796 return state->unbindLoc(*L);
797}
798
Ted Kremenek9c378f72011-08-12 23:37:29 +0000799bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
Jordy Rose19c5dd12010-07-27 01:37:31 +0000800 const MemRegion *MR) {
Ted Kremenek96979342011-08-12 20:02:48 +0000801 const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000802
Jordy Rose096aef92011-08-12 21:41:07 +0000803 switch (MR->getKind()) {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000804 case MemRegion::FunctionTextRegionKind: {
Jordy Rose096aef92011-08-12 21:41:07 +0000805 const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000806 if (FD)
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000807 os << "the address of the function '" << *FD << '\'';
Jordy Rose19c5dd12010-07-27 01:37:31 +0000808 else
809 os << "the address of a function";
810 return true;
811 }
812 case MemRegion::BlockTextRegionKind:
813 os << "block text";
814 return true;
815 case MemRegion::BlockDataRegionKind:
816 os << "a block";
817 return true;
818 case MemRegion::CXXThisRegionKind:
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000819 case MemRegion::CXXTempObjectRegionKind:
Ted Kremenek96979342011-08-12 20:02:48 +0000820 os << "a C++ temp object of type " << TVR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000821 return true;
822 case MemRegion::VarRegionKind:
Ted Kremenek96979342011-08-12 20:02:48 +0000823 os << "a variable of type" << TVR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000824 return true;
825 case MemRegion::FieldRegionKind:
Ted Kremenek96979342011-08-12 20:02:48 +0000826 os << "a field of type " << TVR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000827 return true;
828 case MemRegion::ObjCIvarRegionKind:
Ted Kremenek96979342011-08-12 20:02:48 +0000829 os << "an instance variable of type " << TVR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000830 return true;
831 default:
832 return false;
833 }
834}
835
Jordy Rosed325ffb2010-07-08 23:57:29 +0000836//===----------------------------------------------------------------------===//
Ted Kremenek9c149532010-12-01 21:57:22 +0000837// evaluation of individual function calls.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000838//===----------------------------------------------------------------------===//
839
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000840void CStringChecker::evalCopyCommon(CheckerContext &C,
841 const CallExpr *CE,
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000842 const ProgramState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000843 const Expr *Size, const Expr *Dest,
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000844 const Expr *Source, bool Restricted,
845 bool IsMempcpy) const {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000846 CurrentFunctionDescription = "memory copy function";
847
Jordy Rosed325ffb2010-07-08 23:57:29 +0000848 // See if the size argument is zero.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000849 SVal sizeVal = state->getSVal(Size);
850 QualType sizeTy = Size->getType();
Jordy Rosed325ffb2010-07-08 23:57:29 +0000851
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000852 const ProgramState *stateZeroSize, *stateNonZeroSize;
Jordy Rose1e022412011-06-16 05:51:02 +0000853 llvm::tie(stateZeroSize, stateNonZeroSize) =
854 assumeZero(C, state, sizeVal, sizeTy);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000855
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000856 // Get the value of the Dest.
857 SVal destVal = state->getSVal(Dest);
858
859 // If the size is zero, there won't be any actual memory access, so
860 // just bind the return value to the destination buffer and return.
861 if (stateZeroSize) {
Jordy Rose22d27172011-06-04 00:04:22 +0000862 stateZeroSize = stateZeroSize->BindExpr(CE, destVal);
Anna Zaks0bd6b112011-10-26 21:06:34 +0000863 C.addTransition(stateZeroSize);
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000864 }
Jordy Rosed325ffb2010-07-08 23:57:29 +0000865
866 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000867 if (stateNonZeroSize) {
Jordy Rose22d27172011-06-04 00:04:22 +0000868 state = stateNonZeroSize;
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000869
870 // Ensure the destination is not null. If it is NULL there will be a
871 // NULL pointer dereference.
872 state = checkNonNull(C, state, Dest, destVal);
873 if (!state)
874 return;
875
876 // Get the value of the Src.
877 SVal srcVal = state->getSVal(Source);
878
879 // Ensure the source is not null. If it is NULL there will be a
880 // NULL pointer dereference.
881 state = checkNonNull(C, state, Source, srcVal);
882 if (!state)
883 return;
884
Jordy Rose7182b962011-06-04 01:50:25 +0000885 // Ensure the accesses are valid and that the buffers do not overlap.
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000886 const char * const writeWarning =
887 "Memory copy function overflows destination buffer";
Jordy Rosee64f3112010-08-16 07:51:42 +0000888 state = CheckBufferAccess(C, state, Size, Dest, Source,
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000889 writeWarning, /* sourceWarning = */ NULL);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000890 if (Restricted)
891 state = CheckOverlap(C, state, Size, Dest, Source);
Jordy Rosee64f3112010-08-16 07:51:42 +0000892
Jordy Rose7182b962011-06-04 01:50:25 +0000893 if (!state)
894 return;
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000895
Jordy Rose7182b962011-06-04 01:50:25 +0000896 // If this is mempcpy, get the byte after the last byte copied and
897 // bind the expr.
898 if (IsMempcpy) {
899 loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
900 assert(destRegVal && "Destination should be a known MemRegionVal here");
901
902 // Get the length to copy.
903 NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
904
905 if (lenValNonLoc) {
906 // Get the byte after the last byte copied.
907 SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
908 *destRegVal,
909 *lenValNonLoc,
910 Dest->getType());
911
912 // The byte after the last byte copied is the return value.
913 state = state->BindExpr(CE, lastElement);
Jordy Rose3f8bb2f2011-06-04 01:47:27 +0000914 } else {
Jordy Rose7182b962011-06-04 01:50:25 +0000915 // If we don't know how much we copied, we can at least
916 // conjure a return value for later.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +0000917 unsigned Count = C.getCurrentBlockCount();
Jordy Rose7182b962011-06-04 01:50:25 +0000918 SVal result =
919 C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
920 state = state->BindExpr(CE, result);
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000921 }
922
Jordy Rose7182b962011-06-04 01:50:25 +0000923 } else {
924 // All other copies return the destination buffer.
925 // (Well, bcopy() has a void return type, but this won't hurt.)
926 state = state->BindExpr(CE, destVal);
Jordy Rosee64f3112010-08-16 07:51:42 +0000927 }
Jordy Rose7182b962011-06-04 01:50:25 +0000928
929 // Invalidate the destination.
930 // FIXME: Even if we can't perfectly model the copy, we should see if we
931 // can use LazyCompoundVals to copy the source values into the destination.
932 // This would probably remove any existing bindings past the end of the
933 // copied region, but that's still an improvement over blank invalidation.
934 state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
Anna Zaks0bd6b112011-10-26 21:06:34 +0000935 C.addTransition(state);
Jordy Rosed325ffb2010-07-08 23:57:29 +0000936 }
937}
938
939
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000940void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000941 // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000942 // The return value is the address of the destination buffer.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000943 const Expr *Dest = CE->getArg(0);
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000944 const ProgramState *state = C.getState();
Jordy Rose3f8bb2f2011-06-04 01:47:27 +0000945
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000946 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
947}
948
949void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
950 // void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
951 // The return value is a pointer to the byte following the last written byte.
952 const Expr *Dest = CE->getArg(0);
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000953 const ProgramState *state = C.getState();
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000954
955 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000956}
957
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000958void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000959 // void *memmove(void *dst, const void *src, size_t n);
960 // The return value is the address of the destination buffer.
961 const Expr *Dest = CE->getArg(0);
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000962 const ProgramState *state = C.getState();
Jordy Rose3f8bb2f2011-06-04 01:47:27 +0000963
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000964 evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000965}
966
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000967void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000968 // void bcopy(const void *src, void *dst, size_t n);
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000969 evalCopyCommon(C, CE, C.getState(),
970 CE->getArg(2), CE->getArg(1), CE->getArg(0));
Jordy Rosed325ffb2010-07-08 23:57:29 +0000971}
972
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +0000973void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000974 // int memcmp(const void *s1, const void *s2, size_t n);
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000975 CurrentFunctionDescription = "memory comparison function";
976
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000977 const Expr *Left = CE->getArg(0);
978 const Expr *Right = CE->getArg(1);
979 const Expr *Size = CE->getArg(2);
980
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000981 const ProgramState *state = C.getState();
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000982 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000983
Jordy Rosed325ffb2010-07-08 23:57:29 +0000984 // See if the size argument is zero.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000985 SVal sizeVal = state->getSVal(Size);
986 QualType sizeTy = Size->getType();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000987
Ted Kremenek18c66fd2011-08-15 22:09:50 +0000988 const ProgramState *stateZeroSize, *stateNonZeroSize;
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000989 llvm::tie(stateZeroSize, stateNonZeroSize) =
990 assumeZero(C, state, sizeVal, sizeTy);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000991
Jordy Rosed325ffb2010-07-08 23:57:29 +0000992 // If the size can be zero, the result will be 0 in that case, and we don't
993 // have to check either of the buffers.
Ted Kremenekc8413fd2010-12-02 07:49:45 +0000994 if (stateZeroSize) {
995 state = stateZeroSize;
996 state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Anna Zaks0bd6b112011-10-26 21:06:34 +0000997 C.addTransition(state);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000998 }
999
Jordy Rosed325ffb2010-07-08 23:57:29 +00001000 // If the size can be nonzero, we have to check the other arguments.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001001 if (stateNonZeroSize) {
1002 state = stateNonZeroSize;
Jordy Rosed325ffb2010-07-08 23:57:29 +00001003 // If we know the two buffers are the same, we know the result is 0.
1004 // First, get the two buffers' addresses. Another checker will have already
1005 // made sure they're not undefined.
1006 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
1007 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
Jordy Rosebc56d1f2010-07-07 08:15:01 +00001008
Jordy Rosed325ffb2010-07-08 23:57:29 +00001009 // See if they are the same.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001010 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001011 const ProgramState *StSameBuf, *StNotSameBuf;
Ted Kremenek28f47b92010-12-01 22:16:56 +00001012 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
Jordy Rosed325ffb2010-07-08 23:57:29 +00001013
Jordy Rose1e022412011-06-16 05:51:02 +00001014 // If the two arguments might be the same buffer, we know the result is 0,
Jordy Rosed325ffb2010-07-08 23:57:29 +00001015 // and we only need to check one size.
1016 if (StSameBuf) {
1017 state = StSameBuf;
1018 state = CheckBufferAccess(C, state, Size, Left);
1019 if (state) {
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001020 state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Anna Zaks0bd6b112011-10-26 21:06:34 +00001021 C.addTransition(state);
Jordy Rosed325ffb2010-07-08 23:57:29 +00001022 }
1023 }
1024
1025 // If the two arguments might be different buffers, we have to check the
1026 // size of both of them.
1027 if (StNotSameBuf) {
1028 state = StNotSameBuf;
1029 state = CheckBufferAccess(C, state, Size, Left, Right);
1030 if (state) {
1031 // The return value is the comparison result, which we don't know.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +00001032 unsigned Count = C.getCurrentBlockCount();
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001033 SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rosed325ffb2010-07-08 23:57:29 +00001034 state = state->BindExpr(CE, CmpV);
Anna Zaks0bd6b112011-10-26 21:06:34 +00001035 C.addTransition(state);
Jordy Rosed325ffb2010-07-08 23:57:29 +00001036 }
1037 }
1038 }
Jordy Rosebc56d1f2010-07-07 08:15:01 +00001039}
1040
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001041void CStringChecker::evalstrLength(CheckerContext &C,
1042 const CallExpr *CE) const {
Jordy Rose19c5dd12010-07-27 01:37:31 +00001043 // size_t strlen(const char *s);
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001044 evalstrLengthCommon(C, CE, /* IsStrnlen = */ false);
1045}
1046
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001047void CStringChecker::evalstrnLength(CheckerContext &C,
1048 const CallExpr *CE) const {
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001049 // size_t strnlen(const char *s, size_t maxlen);
1050 evalstrLengthCommon(C, CE, /* IsStrnlen = */ true);
1051}
1052
1053void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001054 bool IsStrnlen) const {
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001055 CurrentFunctionDescription = "string length function";
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001056 const ProgramState *state = C.getState();
Jordy Rose793bff32011-06-14 01:15:31 +00001057
1058 if (IsStrnlen) {
1059 const Expr *maxlenExpr = CE->getArg(1);
1060 SVal maxlenVal = state->getSVal(maxlenExpr);
1061
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001062 const ProgramState *stateZeroSize, *stateNonZeroSize;
Jordy Rose793bff32011-06-14 01:15:31 +00001063 llvm::tie(stateZeroSize, stateNonZeroSize) =
1064 assumeZero(C, state, maxlenVal, maxlenExpr->getType());
1065
1066 // If the size can be zero, the result will be 0 in that case, and we don't
1067 // have to check the string itself.
1068 if (stateZeroSize) {
1069 SVal zero = C.getSValBuilder().makeZeroVal(CE->getType());
1070 stateZeroSize = stateZeroSize->BindExpr(CE, zero);
Anna Zaks0bd6b112011-10-26 21:06:34 +00001071 C.addTransition(stateZeroSize);
Jordy Rose793bff32011-06-14 01:15:31 +00001072 }
1073
1074 // If the size is GUARANTEED to be zero, we're done!
1075 if (!stateNonZeroSize)
1076 return;
1077
1078 // Otherwise, record the assumption that the size is nonzero.
1079 state = stateNonZeroSize;
1080 }
1081
1082 // Check that the string argument is non-null.
Jordy Rose19c5dd12010-07-27 01:37:31 +00001083 const Expr *Arg = CE->getArg(0);
1084 SVal ArgVal = state->getSVal(Arg);
1085
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001086 state = checkNonNull(C, state, Arg, ArgVal);
Jordy Rose19c5dd12010-07-27 01:37:31 +00001087
Jordy Rosebd32bee2011-06-14 01:26:48 +00001088 if (!state)
1089 return;
Jordy Rosea5261542010-08-14 21:02:52 +00001090
Jordy Rosebd32bee2011-06-14 01:26:48 +00001091 SVal strLength = getCStringLength(C, state, Arg, ArgVal);
Jordy Rosea5261542010-08-14 21:02:52 +00001092
Jordy Rosebd32bee2011-06-14 01:26:48 +00001093 // If the argument isn't a valid C string, there's no valid state to
1094 // transition to.
1095 if (strLength.isUndef())
1096 return;
Jordy Rose793bff32011-06-14 01:15:31 +00001097
Jordy Rosebd32bee2011-06-14 01:26:48 +00001098 DefinedOrUnknownSVal result = UnknownVal();
Jordy Rose793bff32011-06-14 01:15:31 +00001099
Jordy Rosebd32bee2011-06-14 01:26:48 +00001100 // If the check is for strnlen() then bind the return value to no more than
1101 // the maxlen value.
1102 if (IsStrnlen) {
Jordy Roseee2fde12011-06-16 05:56:50 +00001103 QualType cmpTy = C.getSValBuilder().getConditionType();
Jordy Rose793bff32011-06-14 01:15:31 +00001104
Jordy Rosebd32bee2011-06-14 01:26:48 +00001105 // It's a little unfortunate to be getting this again,
1106 // but it's not that expensive...
1107 const Expr *maxlenExpr = CE->getArg(1);
1108 SVal maxlenVal = state->getSVal(maxlenExpr);
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001109
Jordy Rosebd32bee2011-06-14 01:26:48 +00001110 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
1111 NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001112
Jordy Rosebd32bee2011-06-14 01:26:48 +00001113 if (strLengthNL && maxlenValNL) {
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001114 const ProgramState *stateStringTooLong, *stateStringNotTooLong;
Jordy Rose793bff32011-06-14 01:15:31 +00001115
Jordy Rosebd32bee2011-06-14 01:26:48 +00001116 // Check if the strLength is greater than the maxlen.
1117 llvm::tie(stateStringTooLong, stateStringNotTooLong) =
1118 state->assume(cast<DefinedOrUnknownSVal>
1119 (C.getSValBuilder().evalBinOpNN(state, BO_GT,
1120 *strLengthNL,
1121 *maxlenValNL,
1122 cmpTy)));
Jordy Rose793bff32011-06-14 01:15:31 +00001123
Jordy Rosebd32bee2011-06-14 01:26:48 +00001124 if (stateStringTooLong && !stateStringNotTooLong) {
1125 // If the string is longer than maxlen, return maxlen.
1126 result = *maxlenValNL;
1127 } else if (stateStringNotTooLong && !stateStringTooLong) {
1128 // If the string is shorter than maxlen, return its length.
1129 result = *strLengthNL;
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001130 }
1131 }
1132
Jordy Rosebd32bee2011-06-14 01:26:48 +00001133 if (result.isUnknown()) {
1134 // If we don't have enough information for a comparison, there's
1135 // no guarantee the full string length will actually be returned.
1136 // All we know is the return value is the min of the string length
1137 // and the limit. This is better than nothing.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +00001138 unsigned Count = C.getCurrentBlockCount();
Jordy Rosebd32bee2011-06-14 01:26:48 +00001139 result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
1140 NonLoc *resultNL = cast<NonLoc>(&result);
1141
1142 if (strLengthNL) {
1143 state = state->assume(cast<DefinedOrUnknownSVal>
1144 (C.getSValBuilder().evalBinOpNN(state, BO_LE,
1145 *resultNL,
1146 *strLengthNL,
1147 cmpTy)), true);
1148 }
1149
1150 if (maxlenValNL) {
1151 state = state->assume(cast<DefinedOrUnknownSVal>
1152 (C.getSValBuilder().evalBinOpNN(state, BO_LE,
1153 *resultNL,
1154 *maxlenValNL,
1155 cmpTy)), true);
1156 }
1157 }
1158
1159 } else {
1160 // This is a plain strlen(), not strnlen().
1161 result = cast<DefinedOrUnknownSVal>(strLength);
1162
1163 // If we don't know the length of the string, conjure a return
1164 // value, so it can be used in constraints, at least.
1165 if (result.isUnknown()) {
Anna Zaks5d0ea6d2011-10-04 20:43:05 +00001166 unsigned Count = C.getCurrentBlockCount();
Jordy Rosebd32bee2011-06-14 01:26:48 +00001167 result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
1168 }
Jordy Rose19c5dd12010-07-27 01:37:31 +00001169 }
Jordy Rosebd32bee2011-06-14 01:26:48 +00001170
1171 // Bind the return value.
1172 assert(!result.isUnknown() && "Should have conjured a value by now");
1173 state = state->BindExpr(CE, result);
Anna Zaks0bd6b112011-10-26 21:06:34 +00001174 C.addTransition(state);
Jordy Rose19c5dd12010-07-27 01:37:31 +00001175}
1176
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001177void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosee64f3112010-08-16 07:51:42 +00001178 // char *strcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001179 evalStrcpyCommon(C, CE,
1180 /* returnEnd = */ false,
1181 /* isBounded = */ false,
1182 /* isAppending = */ false);
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001183}
1184
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001185void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosec1525862011-06-04 00:05:23 +00001186 // char *strncpy(char *restrict dst, const char *restrict src, size_t n);
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001187 evalStrcpyCommon(C, CE,
1188 /* returnEnd = */ false,
1189 /* isBounded = */ true,
1190 /* isAppending = */ false);
Jordy Rosee64f3112010-08-16 07:51:42 +00001191}
1192
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001193void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
Jordy Rosee64f3112010-08-16 07:51:42 +00001194 // char *stpcpy(char *restrict dst, const char *restrict src);
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001195 evalStrcpyCommon(C, CE,
1196 /* returnEnd = */ true,
1197 /* isBounded = */ false,
1198 /* isAppending = */ false);
1199}
1200
1201void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
1202 //char *strcat(char *restrict s1, const char *restrict s2);
1203 evalStrcpyCommon(C, CE,
1204 /* returnEnd = */ false,
1205 /* isBounded = */ false,
1206 /* isAppending = */ true);
1207}
1208
1209void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
1210 //char *strncat(char *restrict s1, const char *restrict s2, size_t n);
1211 evalStrcpyCommon(C, CE,
1212 /* returnEnd = */ false,
1213 /* isBounded = */ true,
1214 /* isAppending = */ true);
Jordy Rosee64f3112010-08-16 07:51:42 +00001215}
1216
Ted Kremenek9c149532010-12-01 21:57:22 +00001217void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001218 bool returnEnd, bool isBounded,
1219 bool isAppending) const {
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001220 CurrentFunctionDescription = "string copy function";
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001221 const ProgramState *state = C.getState();
Jordy Rosee64f3112010-08-16 07:51:42 +00001222
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001223 // Check that the destination is non-null.
Jordy Rosee64f3112010-08-16 07:51:42 +00001224 const Expr *Dst = CE->getArg(0);
1225 SVal DstVal = state->getSVal(Dst);
1226
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001227 state = checkNonNull(C, state, Dst, DstVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001228 if (!state)
1229 return;
1230
1231 // Check that the source is non-null.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001232 const Expr *srcExpr = CE->getArg(1);
1233 SVal srcVal = state->getSVal(srcExpr);
1234 state = checkNonNull(C, state, srcExpr, srcVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001235 if (!state)
1236 return;
1237
1238 // Get the string length of the source.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001239 SVal strLength = getCStringLength(C, state, srcExpr, srcVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001240
1241 // If the source isn't a valid C string, give up.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001242 if (strLength.isUndef())
Jordy Rosee64f3112010-08-16 07:51:42 +00001243 return;
1244
Jordy Rosed5af0e12011-06-15 05:52:56 +00001245 SValBuilder &svalBuilder = C.getSValBuilder();
1246 QualType cmpTy = svalBuilder.getConditionType();
Jordy Rose8912aae2011-06-20 21:55:40 +00001247 QualType sizeTy = svalBuilder.getContext().getSizeType();
Jordy Rosed5af0e12011-06-15 05:52:56 +00001248
Jordy Rose8912aae2011-06-20 21:55:40 +00001249 // These two values allow checking two kinds of errors:
1250 // - actual overflows caused by a source that doesn't fit in the destination
1251 // - potential overflows caused by a bound that could exceed the destination
Jordy Rosed5af0e12011-06-15 05:52:56 +00001252 SVal amountCopied = UnknownVal();
Jordy Rose8912aae2011-06-20 21:55:40 +00001253 SVal maxLastElementIndex = UnknownVal();
1254 const char *boundWarning = NULL;
Jordy Rosed5af0e12011-06-15 05:52:56 +00001255
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001256 // If the function is strncpy, strncat, etc... it is bounded.
1257 if (isBounded) {
1258 // Get the max number of characters to copy.
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001259 const Expr *lenExpr = CE->getArg(2);
1260 SVal lenVal = state->getSVal(lenExpr);
1261
Jordy Rosed5af0e12011-06-15 05:52:56 +00001262 // Protect against misdeclared strncpy().
Jordy Rose8912aae2011-06-20 21:55:40 +00001263 lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType());
Jordy Rosed5af0e12011-06-15 05:52:56 +00001264
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001265 NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
1266 NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
1267
Jordy Rosed5af0e12011-06-15 05:52:56 +00001268 // If we know both values, we might be able to figure out how much
1269 // we're copying.
1270 if (strLengthNL && lenValNL) {
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001271 const ProgramState *stateSourceTooLong, *stateSourceNotTooLong;
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001272
Jordy Rosed5af0e12011-06-15 05:52:56 +00001273 // Check if the max number to copy is less than the length of the src.
Jordy Rose8912aae2011-06-20 21:55:40 +00001274 // If the bound is equal to the source length, strncpy won't null-
1275 // terminate the result!
Jordy Rosed5af0e12011-06-15 05:52:56 +00001276 llvm::tie(stateSourceTooLong, stateSourceNotTooLong) =
1277 state->assume(cast<DefinedOrUnknownSVal>
Jordy Rose8912aae2011-06-20 21:55:40 +00001278 (svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL,
Jordy Rosed5af0e12011-06-15 05:52:56 +00001279 *lenValNL, cmpTy)));
1280
1281 if (stateSourceTooLong && !stateSourceNotTooLong) {
1282 // Max number to copy is less than the length of the src, so the actual
1283 // strLength copied is the max number arg.
1284 state = stateSourceTooLong;
1285 amountCopied = lenVal;
1286
1287 } else if (!stateSourceTooLong && stateSourceNotTooLong) {
1288 // The source buffer entirely fits in the bound.
1289 state = stateSourceNotTooLong;
1290 amountCopied = strLength;
1291 }
1292 }
1293
Jordy Rose5e5f1502011-06-20 03:49:16 +00001294 // We still want to know if the bound is known to be too large.
Jordy Rose8912aae2011-06-20 21:55:40 +00001295 if (lenValNL) {
1296 if (isAppending) {
1297 // For strncat, the check is strlen(dst) + lenVal < sizeof(dst)
1298
1299 // Get the string length of the destination. If the destination is
1300 // memory that can't have a string length, we shouldn't be copying
1301 // into it anyway.
1302 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
1303 if (dstStrLength.isUndef())
1304 return;
1305
1306 if (NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength)) {
1307 maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Add,
1308 *lenValNL,
1309 *dstStrLengthNL,
1310 sizeTy);
1311 boundWarning = "Size argument is greater than the free space in the "
1312 "destination buffer";
1313 }
1314
1315 } else {
1316 // For strncpy, this is just checking that lenVal <= sizeof(dst)
1317 // (Yes, strncpy and strncat differ in how they treat termination.
1318 // strncat ALWAYS terminates, but strncpy doesn't.)
1319 NonLoc one = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
1320 maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL,
1321 one, sizeTy);
1322 boundWarning = "Size argument is greater than the length of the "
1323 "destination buffer";
1324 }
1325 }
Jordy Rose5e5f1502011-06-20 03:49:16 +00001326
Jordy Rosed5af0e12011-06-15 05:52:56 +00001327 // If we couldn't pin down the copy length, at least bound it.
Jordy Rose8912aae2011-06-20 21:55:40 +00001328 // FIXME: We should actually run this code path for append as well, but
1329 // right now it creates problems with constraints (since we can end up
1330 // trying to pass constraints from symbol to symbol).
1331 if (amountCopied.isUnknown() && !isAppending) {
Jordy Rosed5af0e12011-06-15 05:52:56 +00001332 // Try to get a "hypothetical" string length symbol, which we can later
1333 // set as a real value if that turns out to be the case.
1334 amountCopied = getCStringLength(C, state, lenExpr, srcVal, true);
1335 assert(!amountCopied.isUndef());
1336
1337 if (NonLoc *amountCopiedNL = dyn_cast<NonLoc>(&amountCopied)) {
1338 if (lenValNL) {
1339 // amountCopied <= lenVal
1340 SVal copiedLessThanBound = svalBuilder.evalBinOpNN(state, BO_LE,
1341 *amountCopiedNL,
1342 *lenValNL,
1343 cmpTy);
1344 state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanBound),
1345 true);
1346 if (!state)
1347 return;
1348 }
1349
1350 if (strLengthNL) {
1351 // amountCopied <= strlen(source)
1352 SVal copiedLessThanSrc = svalBuilder.evalBinOpNN(state, BO_LE,
1353 *amountCopiedNL,
1354 *strLengthNL,
1355 cmpTy);
1356 state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
1357 true);
1358 if (!state)
1359 return;
1360 }
1361 }
1362 }
1363
1364 } else {
1365 // The function isn't bounded. The amount copied should match the length
1366 // of the source buffer.
1367 amountCopied = strLength;
Ted Kremenek0ef473f2011-02-22 04:58:34 +00001368 }
1369
Jordy Rosed5af0e12011-06-15 05:52:56 +00001370 assert(state);
1371
1372 // This represents the number of characters copied into the destination
1373 // buffer. (It may not actually be the strlen if the destination buffer
1374 // is not terminated.)
1375 SVal finalStrLength = UnknownVal();
1376
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001377 // If this is an appending function (strcat, strncat...) then set the
1378 // string length to strlen(src) + strlen(dst) since the buffer will
1379 // ultimately contain both.
1380 if (isAppending) {
Jordy Rose1e022412011-06-16 05:51:02 +00001381 // Get the string length of the destination. If the destination is memory
1382 // that can't have a string length, we shouldn't be copying into it anyway.
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001383 SVal dstStrLength = getCStringLength(C, state, Dst, DstVal);
1384 if (dstStrLength.isUndef())
1385 return;
1386
Jordy Rosed5af0e12011-06-15 05:52:56 +00001387 NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&amountCopied);
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001388 NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
1389
Jordy Rosed5af0e12011-06-15 05:52:56 +00001390 // If we know both string lengths, we might know the final string length.
1391 if (srcStrLengthNL && dstStrLengthNL) {
1392 // Make sure the two lengths together don't overflow a size_t.
1393 state = checkAdditionOverflow(C, state, *srcStrLengthNL, *dstStrLengthNL);
1394 if (!state)
1395 return;
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001396
Jordy Rosed5af0e12011-06-15 05:52:56 +00001397 finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *srcStrLengthNL,
1398 *dstStrLengthNL, sizeTy);
1399 }
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001400
Jordy Rosed5af0e12011-06-15 05:52:56 +00001401 // If we couldn't get a single value for the final string length,
1402 // we can at least bound it by the individual lengths.
1403 if (finalStrLength.isUnknown()) {
1404 // Try to get a "hypothetical" string length symbol, which we can later
1405 // set as a real value if that turns out to be the case.
1406 finalStrLength = getCStringLength(C, state, CE, DstVal, true);
1407 assert(!finalStrLength.isUndef());
1408
1409 if (NonLoc *finalStrLengthNL = dyn_cast<NonLoc>(&finalStrLength)) {
1410 if (srcStrLengthNL) {
1411 // finalStrLength >= srcStrLength
1412 SVal sourceInResult = svalBuilder.evalBinOpNN(state, BO_GE,
1413 *finalStrLengthNL,
1414 *srcStrLengthNL,
1415 cmpTy);
1416 state = state->assume(cast<DefinedOrUnknownSVal>(sourceInResult),
1417 true);
1418 if (!state)
1419 return;
1420 }
1421
1422 if (dstStrLengthNL) {
1423 // finalStrLength >= dstStrLength
1424 SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE,
1425 *finalStrLengthNL,
1426 *dstStrLengthNL,
1427 cmpTy);
1428 state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
1429 true);
1430 if (!state)
1431 return;
1432 }
1433 }
1434 }
1435
1436 } else {
1437 // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and
1438 // the final string length will match the input string length.
1439 finalStrLength = amountCopied;
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001440 }
1441
Jordy Rosed5af0e12011-06-15 05:52:56 +00001442 // The final result of the function will either be a pointer past the last
1443 // copied element, or a pointer to the start of the destination buffer.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001444 SVal Result = (returnEnd ? UnknownVal() : DstVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001445
Jordy Rosed5af0e12011-06-15 05:52:56 +00001446 assert(state);
1447
Jordy Rosee64f3112010-08-16 07:51:42 +00001448 // If the destination is a MemRegion, try to check for a buffer overflow and
1449 // record the new string length.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001450 if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
Jordy Rose8912aae2011-06-20 21:55:40 +00001451 QualType ptrTy = Dst->getType();
1452
1453 // If we have an exact value on a bounded copy, use that to check for
1454 // overflows, rather than our estimate about how much is actually copied.
1455 if (boundWarning) {
1456 if (NonLoc *maxLastNL = dyn_cast<NonLoc>(&maxLastElementIndex)) {
1457 SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
1458 *maxLastNL, ptrTy);
1459 state = CheckLocation(C, state, CE->getArg(2), maxLastElement,
1460 boundWarning);
1461 if (!state)
1462 return;
1463 }
1464 }
1465
1466 // Then, if the final length is known...
Jordy Rosed5af0e12011-06-15 05:52:56 +00001467 if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&finalStrLength)) {
1468 SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
Jordy Rose8912aae2011-06-20 21:55:40 +00001469 *knownStrLength, ptrTy);
Jordy Rosee64f3112010-08-16 07:51:42 +00001470
Jordy Rose8912aae2011-06-20 21:55:40 +00001471 // ...and we haven't checked the bound, we'll check the actual copy.
1472 if (!boundWarning) {
1473 const char * const warningMsg =
1474 "String copy function overflows destination buffer";
1475 state = CheckLocation(C, state, Dst, lastElement, warningMsg);
1476 if (!state)
1477 return;
1478 }
Jordy Rosee64f3112010-08-16 07:51:42 +00001479
1480 // If this is a stpcpy-style copy, the last element is the return value.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001481 if (returnEnd)
1482 Result = lastElement;
Jordy Rosee64f3112010-08-16 07:51:42 +00001483 }
1484
1485 // Invalidate the destination. This must happen before we set the C string
1486 // length because invalidation will clear the length.
1487 // FIXME: Even if we can't perfectly model the copy, we should see if we
1488 // can use LazyCompoundVals to copy the source values into the destination.
1489 // This would probably remove any existing bindings past the end of the
1490 // string, but that's still an improvement over blank invalidation.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001491 state = InvalidateBuffer(C, state, Dst, *dstRegVal);
Jordy Rosee64f3112010-08-16 07:51:42 +00001492
Jordy Rose5e5f1502011-06-20 03:49:16 +00001493 // Set the C string length of the destination, if we know it.
Jordy Rose8912aae2011-06-20 21:55:40 +00001494 if (isBounded && !isAppending) {
1495 // strncpy is annoying in that it doesn't guarantee to null-terminate
1496 // the result string. If the original string didn't fit entirely inside
1497 // the bound (including the null-terminator), we don't know how long the
1498 // result is.
1499 if (amountCopied != strLength)
1500 finalStrLength = UnknownVal();
1501 }
1502 state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength);
Jordy Rosee64f3112010-08-16 07:51:42 +00001503 }
1504
Jordy Rosed5af0e12011-06-15 05:52:56 +00001505 assert(state);
1506
Jordy Rosee64f3112010-08-16 07:51:42 +00001507 // If this is a stpcpy-style copy, but we were unable to check for a buffer
1508 // overflow, we still need a result. Conjure a return value.
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001509 if (returnEnd && Result.isUnknown()) {
Anna Zaks5d0ea6d2011-10-04 20:43:05 +00001510 unsigned Count = C.getCurrentBlockCount();
Jordy Rosed5af0e12011-06-15 05:52:56 +00001511 Result = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
Jordy Rosee64f3112010-08-16 07:51:42 +00001512 }
1513
1514 // Set the return value.
1515 state = state->BindExpr(CE, Result);
Anna Zaks0bd6b112011-10-26 21:06:34 +00001516 C.addTransition(state);
Jordy Rosee64f3112010-08-16 07:51:42 +00001517}
1518
Lenny Maiorani318dd922011-04-12 17:08:43 +00001519void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
Jordy Roseadc42d42011-06-16 07:13:34 +00001520 //int strcmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001521 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001522}
Lenny Maiorani318dd922011-04-12 17:08:43 +00001523
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001524void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
Jordy Roseadc42d42011-06-16 07:13:34 +00001525 //int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001526 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
1527}
1528
1529void CStringChecker::evalStrcasecmp(CheckerContext &C,
1530 const CallExpr *CE) const {
Jordy Roseadc42d42011-06-16 07:13:34 +00001531 //int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001532 evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001533}
1534
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001535void CStringChecker::evalStrncasecmp(CheckerContext &C,
1536 const CallExpr *CE) const {
Jordy Roseadc42d42011-06-16 07:13:34 +00001537 //int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001538 evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true);
1539}
1540
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001541void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001542 bool isBounded, bool ignoreCase) const {
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001543 CurrentFunctionDescription = "string comparison function";
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001544 const ProgramState *state = C.getState();
Lenny Maiorani318dd922011-04-12 17:08:43 +00001545
1546 // Check that the first string is non-null
1547 const Expr *s1 = CE->getArg(0);
1548 SVal s1Val = state->getSVal(s1);
1549 state = checkNonNull(C, state, s1, s1Val);
1550 if (!state)
1551 return;
1552
1553 // Check that the second string is non-null.
1554 const Expr *s2 = CE->getArg(1);
1555 SVal s2Val = state->getSVal(s2);
1556 state = checkNonNull(C, state, s2, s2Val);
1557 if (!state)
1558 return;
1559
1560 // Get the string length of the first string or give up.
1561 SVal s1Length = getCStringLength(C, state, s1, s1Val);
1562 if (s1Length.isUndef())
1563 return;
1564
1565 // Get the string length of the second string or give up.
1566 SVal s2Length = getCStringLength(C, state, s2, s2Val);
1567 if (s2Length.isUndef())
1568 return;
1569
Jordy Roseadc42d42011-06-16 07:13:34 +00001570 // If we know the two buffers are the same, we know the result is 0.
1571 // First, get the two buffers' addresses. Another checker will have already
1572 // made sure they're not undefined.
1573 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(s1Val);
1574 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(s2Val);
Lenny Maiorani318dd922011-04-12 17:08:43 +00001575
Jordy Roseadc42d42011-06-16 07:13:34 +00001576 // See if they are the same.
Lenny Maiorani318dd922011-04-12 17:08:43 +00001577 SValBuilder &svalBuilder = C.getSValBuilder();
Jordy Roseadc42d42011-06-16 07:13:34 +00001578 DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001579 const ProgramState *StSameBuf, *StNotSameBuf;
Jordy Roseadc42d42011-06-16 07:13:34 +00001580 llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
Lenny Maiorani318dd922011-04-12 17:08:43 +00001581
Jordy Roseadc42d42011-06-16 07:13:34 +00001582 // If the two arguments might be the same buffer, we know the result is 0,
1583 // and we only need to check one size.
1584 if (StSameBuf) {
1585 StSameBuf = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
Anna Zaks0bd6b112011-10-26 21:06:34 +00001586 C.addTransition(StSameBuf);
Jordy Roseadc42d42011-06-16 07:13:34 +00001587
1588 // If the two arguments are GUARANTEED to be the same, we're done!
1589 if (!StNotSameBuf)
1590 return;
1591 }
1592
1593 assert(StNotSameBuf);
1594 state = StNotSameBuf;
1595
1596 // At this point we can go about comparing the two buffers.
1597 // For now, we only do this if they're both known string literals.
1598
1599 // Attempt to extract string literals from both expressions.
1600 const StringLiteral *s1StrLiteral = getCStringLiteral(C, state, s1, s1Val);
1601 const StringLiteral *s2StrLiteral = getCStringLiteral(C, state, s2, s2Val);
1602 bool canComputeResult = false;
1603
1604 if (s1StrLiteral && s2StrLiteral) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00001605 StringRef s1StrRef = s1StrLiteral->getString();
1606 StringRef s2StrRef = s2StrLiteral->getString();
Jordy Roseadc42d42011-06-16 07:13:34 +00001607
1608 if (isBounded) {
1609 // Get the max number of characters to compare.
1610 const Expr *lenExpr = CE->getArg(2);
1611 SVal lenVal = state->getSVal(lenExpr);
1612
1613 // If the length is known, we can get the right substrings.
1614 if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) {
1615 // Create substrings of each to compare the prefix.
1616 s1StrRef = s1StrRef.substr(0, (size_t)len->getZExtValue());
1617 s2StrRef = s2StrRef.substr(0, (size_t)len->getZExtValue());
1618 canComputeResult = true;
1619 }
1620 } else {
1621 // This is a normal, unbounded strcmp.
1622 canComputeResult = true;
1623 }
1624
1625 if (canComputeResult) {
1626 // Real strcmp stops at null characters.
1627 size_t s1Term = s1StrRef.find('\0');
Chris Lattner5f9e2722011-07-23 10:55:15 +00001628 if (s1Term != StringRef::npos)
Jordy Roseadc42d42011-06-16 07:13:34 +00001629 s1StrRef = s1StrRef.substr(0, s1Term);
1630
1631 size_t s2Term = s2StrRef.find('\0');
Chris Lattner5f9e2722011-07-23 10:55:15 +00001632 if (s2Term != StringRef::npos)
Jordy Roseadc42d42011-06-16 07:13:34 +00001633 s2StrRef = s2StrRef.substr(0, s2Term);
1634
1635 // Use StringRef's comparison methods to compute the actual result.
1636 int result;
1637
1638 if (ignoreCase) {
1639 // Compare string 1 to string 2 the same way strcasecmp() does.
1640 result = s1StrRef.compare_lower(s2StrRef);
1641 } else {
1642 // Compare string 1 to string 2 the same way strcmp() does.
1643 result = s1StrRef.compare(s2StrRef);
1644 }
1645
1646 // Build the SVal of the comparison and bind the return value.
1647 SVal resultVal = svalBuilder.makeIntVal(result, CE->getType());
1648 state = state->BindExpr(CE, resultVal);
1649 }
1650 }
1651
1652 if (!canComputeResult) {
1653 // Conjure a symbolic value. It's the best we can do.
Anna Zaks5d0ea6d2011-10-04 20:43:05 +00001654 unsigned Count = C.getCurrentBlockCount();
Jordy Roseadc42d42011-06-16 07:13:34 +00001655 SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
1656 state = state->BindExpr(CE, resultVal);
1657 }
1658
1659 // Record this as a possible path.
Anna Zaks0bd6b112011-10-26 21:06:34 +00001660 C.addTransition(state);
Lenny Maiorani318dd922011-04-12 17:08:43 +00001661}
1662
Jordy Rosed325ffb2010-07-08 23:57:29 +00001663//===----------------------------------------------------------------------===//
Jordy Rosea5261542010-08-14 21:02:52 +00001664// The driver method, and other Checker callbacks.
Jordy Rosed325ffb2010-07-08 23:57:29 +00001665//===----------------------------------------------------------------------===//
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001666
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001667bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
Anna Zaksb805c8f2011-12-01 05:57:37 +00001668 StringRef Name = C.getCalleeName(CE);
1669 if (Name.empty())
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001670 return false;
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001671 if (Name.startswith("__builtin_"))
1672 Name = Name.substr(10);
1673
Ted Kremenek9c149532010-12-01 21:57:22 +00001674 FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
1675 .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
Jordy Rosebe460d82011-06-03 23:42:56 +00001676 .Cases("mempcpy", "__mempcpy_chk", &CStringChecker::evalMempcpy)
Ted Kremenek9c149532010-12-01 21:57:22 +00001677 .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
1678 .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
1679 .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
Jordy Rose5e5f1502011-06-20 03:49:16 +00001680 .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
Ted Kremenek9c149532010-12-01 21:57:22 +00001681 .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
Lenny Maiorani067bbd02011-04-09 15:12:58 +00001682 .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat)
1683 .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat)
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001684 .Case("strlen", &CStringChecker::evalstrLength)
Ted Kremenekbe4242c2011-02-22 04:55:05 +00001685 .Case("strnlen", &CStringChecker::evalstrnLength)
Lenny Maiorani318dd922011-04-12 17:08:43 +00001686 .Case("strcmp", &CStringChecker::evalStrcmp)
Lenny Maiorani357f6ee2011-04-25 22:21:00 +00001687 .Case("strncmp", &CStringChecker::evalStrncmp)
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001688 .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001689 .Case("strncasecmp", &CStringChecker::evalStrncasecmp)
Ted Kremenek9c149532010-12-01 21:57:22 +00001690 .Case("bcopy", &CStringChecker::evalBcopy)
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001691 .Default(NULL);
1692
Jordy Rosed325ffb2010-07-08 23:57:29 +00001693 // If the callee isn't a string function, let another checker handle it.
Ted Kremenek9c149532010-12-01 21:57:22 +00001694 if (!evalFunction)
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001695 return false;
1696
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001697 // Make sure each function sets its own description.
1698 // (But don't bother in a release build.)
1699 assert(!(CurrentFunctionDescription = NULL));
1700
Jordy Rosed325ffb2010-07-08 23:57:29 +00001701 // Check and evaluate the call.
Ted Kremenek9c149532010-12-01 21:57:22 +00001702 (this->*evalFunction)(C, CE);
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001703 return true;
1704}
Jordy Rosea5261542010-08-14 21:02:52 +00001705
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001706void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001707 // Record string length for char a[] = "abc";
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001708 const ProgramState *state = C.getState();
Jordy Rosea5261542010-08-14 21:02:52 +00001709
1710 for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
1711 I != E; ++I) {
1712 const VarDecl *D = dyn_cast<VarDecl>(*I);
1713 if (!D)
1714 continue;
1715
1716 // FIXME: Handle array fields of structs.
1717 if (!D->getType()->isArrayType())
1718 continue;
1719
1720 const Expr *Init = D->getInit();
1721 if (!Init)
1722 continue;
1723 if (!isa<StringLiteral>(Init))
1724 continue;
1725
Anna Zaks39ac1872011-10-26 21:06:44 +00001726 Loc VarLoc = state->getLValue(D, C.getLocationContext());
Jordy Rosea5261542010-08-14 21:02:52 +00001727 const MemRegion *MR = VarLoc.getAsRegion();
1728 if (!MR)
1729 continue;
1730
1731 SVal StrVal = state->getSVal(Init);
1732 assert(StrVal.isValid() && "Initializer string is unknown or undefined");
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001733 DefinedOrUnknownSVal strLength
1734 = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
Jordy Rosea5261542010-08-14 21:02:52 +00001735
Ted Kremenekc8413fd2010-12-02 07:49:45 +00001736 state = state->set<CStringLength>(MR, strLength);
Jordy Rosea5261542010-08-14 21:02:52 +00001737 }
1738
Anna Zaks0bd6b112011-10-26 21:06:34 +00001739 C.addTransition(state);
Jordy Rosea5261542010-08-14 21:02:52 +00001740}
1741
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001742bool CStringChecker::wantsRegionChangeUpdate(const ProgramState *state) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001743 CStringLength::EntryMap Entries = state->get<CStringLength>();
1744 return !Entries.isEmpty();
1745}
1746
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001747const ProgramState *
1748CStringChecker::checkRegionChanges(const ProgramState *state,
Ted Kremenek35bdbf42011-05-02 19:42:42 +00001749 const StoreManager::InvalidatedSymbols *,
Jordy Rose537716a2011-08-27 22:51:26 +00001750 ArrayRef<const MemRegion *> ExplicitRegions,
1751 ArrayRef<const MemRegion *> Regions) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001752 CStringLength::EntryMap Entries = state->get<CStringLength>();
1753 if (Entries.isEmpty())
1754 return state;
1755
1756 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
1757 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
1758
1759 // First build sets for the changed regions and their super-regions.
Jordy Rose537716a2011-08-27 22:51:26 +00001760 for (ArrayRef<const MemRegion *>::iterator
1761 I = Regions.begin(), E = Regions.end(); I != E; ++I) {
1762 const MemRegion *MR = *I;
Jordy Rosea5261542010-08-14 21:02:52 +00001763 Invalidated.insert(MR);
1764
1765 SuperRegions.insert(MR);
1766 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
1767 MR = SR->getSuperRegion();
1768 SuperRegions.insert(MR);
1769 }
1770 }
1771
1772 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1773
1774 // Then loop over the entries in the current state.
1775 for (CStringLength::EntryMap::iterator I = Entries.begin(),
1776 E = Entries.end(); I != E; ++I) {
1777 const MemRegion *MR = I.getKey();
1778
1779 // Is this entry for a super-region of a changed region?
1780 if (SuperRegions.count(MR)) {
Ted Kremenek3baf6722010-11-24 00:54:37 +00001781 Entries = F.remove(Entries, MR);
Jordy Rosea5261542010-08-14 21:02:52 +00001782 continue;
1783 }
1784
1785 // Is this entry for a sub-region of a changed region?
1786 const MemRegion *Super = MR;
1787 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
1788 Super = SR->getSuperRegion();
1789 if (Invalidated.count(Super)) {
Ted Kremenek3baf6722010-11-24 00:54:37 +00001790 Entries = F.remove(Entries, MR);
Jordy Rosea5261542010-08-14 21:02:52 +00001791 break;
1792 }
1793 }
1794 }
1795
1796 return state->set<CStringLength>(Entries);
1797}
1798
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001799void CStringChecker::checkLiveSymbols(const ProgramState *state,
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001800 SymbolReaper &SR) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001801 // Mark all symbols in our string length map as valid.
1802 CStringLength::EntryMap Entries = state->get<CStringLength>();
1803
1804 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1805 I != E; ++I) {
1806 SVal Len = I.getData();
Jordy Rosed5af0e12011-06-15 05:52:56 +00001807
Anna Zaks1d1d5152011-12-06 23:12:33 +00001808 for (SymExpr::symbol_iterator si = Len.symbol_begin(),
1809 se = Len.symbol_end(); si != se; ++si)
Jordy Rosed5af0e12011-06-15 05:52:56 +00001810 SR.markInUse(*si);
Jordy Rosea5261542010-08-14 21:02:52 +00001811 }
1812}
1813
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001814void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
1815 CheckerContext &C) const {
Jordy Rosea5261542010-08-14 21:02:52 +00001816 if (!SR.hasDeadSymbols())
1817 return;
1818
Ted Kremenek18c66fd2011-08-15 22:09:50 +00001819 const ProgramState *state = C.getState();
Jordy Rosea5261542010-08-14 21:02:52 +00001820 CStringLength::EntryMap Entries = state->get<CStringLength>();
1821 if (Entries.isEmpty())
1822 return;
1823
1824 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
1825 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
1826 I != E; ++I) {
1827 SVal Len = I.getData();
1828 if (SymbolRef Sym = Len.getAsSymbol()) {
1829 if (SR.isDead(Sym))
Ted Kremenek3baf6722010-11-24 00:54:37 +00001830 Entries = F.remove(Entries, I.getKey());
Jordy Rosea5261542010-08-14 21:02:52 +00001831 }
1832 }
1833
1834 state = state->set<CStringLength>(Entries);
Anna Zaks0bd6b112011-10-26 21:06:34 +00001835 C.addTransition(state);
Jordy Rosea5261542010-08-14 21:02:52 +00001836}
Argyrios Kyrtzidis183ff982011-02-24 01:05:30 +00001837
1838void ento::registerCStringChecker(CheckerManager &mgr) {
1839 mgr.registerChecker<CStringChecker>();
1840}