blob: bf3316fbdabef32c2a54278b6dadf08914c8dc35 [file] [log] [blame]
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001//= CStringChecker.h - Checks calls to C string functions ----------*- C++ -*-//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This defines CStringChecker, which is an assortment of checks on calls
11// to functions in <string.h>.
12//
13//===----------------------------------------------------------------------===//
14
15#include "GRExprEngineExperimentalChecks.h"
16#include "clang/Checker/BugReporter/BugType.h"
17#include "clang/Checker/PathSensitive/CheckerVisitor.h"
Jordy Rosea5261542010-08-14 21:02:52 +000018#include "clang/Checker/PathSensitive/GRStateTrait.h"
Jordy Roseccbf7ee2010-07-06 23:11:01 +000019#include "llvm/ADT/StringSwitch.h"
20
21using namespace clang;
22
23namespace {
24class CStringChecker : public CheckerVisitor<CStringChecker> {
Jordy Rose19c5dd12010-07-27 01:37:31 +000025 BugType *BT_Null, *BT_Bounds, *BT_Overlap, *BT_NotCString;
Jordy Roseccbf7ee2010-07-06 23:11:01 +000026public:
27 CStringChecker()
Jordy Rose19c5dd12010-07-27 01:37:31 +000028 : BT_Null(0), BT_Bounds(0), BT_Overlap(0), BT_NotCString(0) {}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000029 static void *getTag() { static int tag; return &tag; }
30
31 bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
Jordy Rosea5261542010-08-14 21:02:52 +000032 void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
33 void MarkLiveSymbols(const GRState *state, SymbolReaper &SR);
34 void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
35 bool WantsRegionChangeUpdate(const GRState *state);
36
37 const GRState *EvalRegionChanges(const GRState *state,
38 const MemRegion * const *Begin,
39 const MemRegion * const *End,
40 bool*);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000041
Jordy Rosed325ffb2010-07-08 23:57:29 +000042 typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000043
Jordy Rosed325ffb2010-07-08 23:57:29 +000044 void EvalMemcpy(CheckerContext &C, const CallExpr *CE);
45 void EvalMemmove(CheckerContext &C, const CallExpr *CE);
46 void EvalBcopy(CheckerContext &C, const CallExpr *CE);
47 void EvalCopyCommon(CheckerContext &C, const GRState *state,
48 const Expr *Size, const Expr *Source, const Expr *Dest,
49 bool Restricted = false);
50
51 void EvalMemcmp(CheckerContext &C, const CallExpr *CE);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000052
Jordy Rose19c5dd12010-07-27 01:37:31 +000053 void EvalStrlen(CheckerContext &C, const CallExpr *CE);
54
Jordy Roseccbf7ee2010-07-06 23:11:01 +000055 // Utility methods
Jordy Rosed325ffb2010-07-08 23:57:29 +000056 std::pair<const GRState*, const GRState*>
57 AssumeZero(CheckerContext &C, const GRState *state, SVal V, QualType Ty);
58
Jordy Rosea5261542010-08-14 21:02:52 +000059 SVal GetCStringLengthForRegion(CheckerContext &C, const GRState *&state,
60 const Expr *Ex, const MemRegion *MR);
61 SVal GetCStringLength(CheckerContext &C, const GRState *&state,
Jordy Rose19c5dd12010-07-27 01:37:31 +000062 const Expr *Ex, SVal Buf);
63
64 bool SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
65 const MemRegion *MR);
66
67 // Re-usable checks
Jordy Rosea6b808c2010-07-07 07:48:06 +000068 const GRState *CheckNonNull(CheckerContext &C, const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +000069 const Expr *S, SVal l);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000070 const GRState *CheckLocation(CheckerContext &C, const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +000071 const Expr *S, SVal l);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000072 const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
73 const Expr *Size,
74 const Expr *FirstBuf,
75 const Expr *SecondBuf = NULL);
76 const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +000077 const Expr *Size, const Expr *First,
78 const Expr *Second);
Jordy Roseccbf7ee2010-07-06 23:11:01 +000079 void EmitOverlapBug(CheckerContext &C, const GRState *state,
80 const Stmt *First, const Stmt *Second);
81};
Jordy Rosea5261542010-08-14 21:02:52 +000082
83class CStringLength {
84public:
85 typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
86};
Jordy Roseccbf7ee2010-07-06 23:11:01 +000087} //end anonymous namespace
88
Jordy Rosea5261542010-08-14 21:02:52 +000089namespace clang {
90 template <>
91 struct GRStateTrait<CStringLength>
92 : public GRStatePartialTrait<CStringLength::EntryMap> {
93 static void *GDMIndex() { return CStringChecker::getTag(); }
94 };
95}
96
Jordy Roseccbf7ee2010-07-06 23:11:01 +000097void clang::RegisterCStringChecker(GRExprEngine &Eng) {
98 Eng.registerCheck(new CStringChecker());
99}
100
Jordy Rosed325ffb2010-07-08 23:57:29 +0000101//===----------------------------------------------------------------------===//
102// Individual checks and utility methods.
103//===----------------------------------------------------------------------===//
104
105std::pair<const GRState*, const GRState*>
106CStringChecker::AssumeZero(CheckerContext &C, const GRState *state, SVal V,
107 QualType Ty) {
108 DefinedSVal *Val = dyn_cast<DefinedSVal>(&V);
109 if (!Val)
110 return std::pair<const GRState*, const GRState *>(state, state);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000111
112 ValueManager &ValMgr = C.getValueManager();
113 SValuator &SV = ValMgr.getSValuator();
114
Jordy Rosed325ffb2010-07-08 23:57:29 +0000115 DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty);
116 DefinedOrUnknownSVal ValIsZero = SV.EvalEQ(state, *Val, Zero);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000117
Jordy Rosed325ffb2010-07-08 23:57:29 +0000118 return state->Assume(ValIsZero);
119}
Jordy Rosea6b808c2010-07-07 07:48:06 +0000120
Jordy Rosed325ffb2010-07-08 23:57:29 +0000121const GRState *CStringChecker::CheckNonNull(CheckerContext &C,
122 const GRState *state,
123 const Expr *S, SVal l) {
124 // If a previous check has failed, propagate the failure.
125 if (!state)
126 return NULL;
127
128 const GRState *stateNull, *stateNonNull;
129 llvm::tie(stateNull, stateNonNull) = AssumeZero(C, state, l, S->getType());
130
131 if (stateNull && !stateNonNull) {
132 ExplodedNode *N = C.GenerateSink(stateNull);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000133 if (!N)
134 return NULL;
135
Jordy Rosed325ffb2010-07-08 23:57:29 +0000136 if (!BT_Null)
137 BT_Null = new BuiltinBug("API",
Jordy Rosea6b808c2010-07-07 07:48:06 +0000138 "Null pointer argument in call to byte string function");
139
140 // Generate a report for this bug.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000141 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000142 EnhancedBugReport *report = new EnhancedBugReport(*BT,
143 BT->getDescription(), N);
144
145 report->addRange(S->getSourceRange());
146 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
147 C.EmitReport(report);
148 return NULL;
149 }
150
151 // From here on, assume that the value is non-null.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000152 assert(stateNonNull);
153 return stateNonNull;
Jordy Rosea6b808c2010-07-07 07:48:06 +0000154}
155
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000156// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
157const GRState *CStringChecker::CheckLocation(CheckerContext &C,
158 const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000159 const Expr *S, SVal l) {
160 // If a previous check has failed, propagate the failure.
161 if (!state)
162 return NULL;
163
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000164 // Check for out of bound array element access.
165 const MemRegion *R = l.getAsRegion();
166 if (!R)
167 return state;
168
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000169 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
170 if (!ER)
171 return state;
172
Zhongxing Xu018220c2010-08-11 06:10:55 +0000173 assert(ER->getValueType() == C.getASTContext().CharTy &&
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000174 "CheckLocation should only be called with char* ElementRegions");
175
176 // Get the size of the array.
177 const SubRegion *Super = cast<SubRegion>(ER->getSuperRegion());
178 ValueManager &ValMgr = C.getValueManager();
179 SVal Extent = ValMgr.convertToArrayIndex(Super->getExtent(ValMgr));
180 DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
181
182 // Get the index of the accessed element.
183 DefinedOrUnknownSVal &Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
184
185 const GRState *StInBound = state->AssumeInBound(Idx, Size, true);
186 const GRState *StOutBound = state->AssumeInBound(Idx, Size, false);
187 if (StOutBound && !StInBound) {
188 ExplodedNode *N = C.GenerateSink(StOutBound);
189 if (!N)
190 return NULL;
191
192 if (!BT_Bounds)
193 BT_Bounds = new BuiltinBug("Out-of-bound array access",
194 "Byte string function accesses out-of-bound array element "
195 "(buffer overflow)");
196
197 // FIXME: It would be nice to eventually make this diagnostic more clear,
198 // e.g., by referencing the original declaration or by saying *why* this
199 // reference is outside the range.
200
201 // Generate a report for this bug.
202 BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds);
203 RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N);
204
205 report->addRange(S->getSourceRange());
206 C.EmitReport(report);
207 return NULL;
208 }
209
210 // Array bound check succeeded. From this point forward the array bound
211 // should always succeed.
212 return StInBound;
213}
214
215const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
216 const GRState *state,
217 const Expr *Size,
218 const Expr *FirstBuf,
219 const Expr *SecondBuf) {
Jordy Rosed325ffb2010-07-08 23:57:29 +0000220 // If a previous check has failed, propagate the failure.
221 if (!state)
222 return NULL;
223
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000224 ValueManager &VM = C.getValueManager();
225 SValuator &SV = VM.getSValuator();
226 ASTContext &Ctx = C.getASTContext();
227
228 QualType SizeTy = Ctx.getSizeType();
229 QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
230
Jordy Rosea6b808c2010-07-07 07:48:06 +0000231 // Check that the first buffer is non-null.
232 SVal BufVal = state->getSVal(FirstBuf);
233 state = CheckNonNull(C, state, FirstBuf, BufVal);
234 if (!state)
235 return NULL;
236
Jordy Rosed325ffb2010-07-08 23:57:29 +0000237 // Get the access length and make sure it is known.
238 SVal LengthVal = state->getSVal(Size);
239 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
240 if (!Length)
241 return state;
242
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000243 // Compute the offset of the last element to be accessed: size-1.
244 NonLoc One = cast<NonLoc>(VM.makeIntVal(1, SizeTy));
245 NonLoc LastOffset = cast<NonLoc>(SV.EvalBinOpNN(state, BinaryOperator::Sub,
246 *Length, One, SizeTy));
247
Jordy Rosea6b808c2010-07-07 07:48:06 +0000248 // Check that the first buffer is sufficently long.
Jordy Roseb6a40262010-08-05 23:11:30 +0000249 SVal BufStart = SV.EvalCast(BufVal, PtrTy, FirstBuf->getType());
250 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
251 SVal BufEnd = SV.EvalBinOpLN(state, BinaryOperator::Add, *BufLoc,
252 LastOffset, PtrTy);
253 state = CheckLocation(C, state, FirstBuf, BufEnd);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000254
Jordy Roseb6a40262010-08-05 23:11:30 +0000255 // If the buffer isn't large enough, abort.
256 if (!state)
257 return NULL;
258 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000259
260 // If there's a second buffer, check it as well.
261 if (SecondBuf) {
262 BufVal = state->getSVal(SecondBuf);
Jordy Rosea6b808c2010-07-07 07:48:06 +0000263 state = CheckNonNull(C, state, SecondBuf, BufVal);
264 if (!state)
265 return NULL;
266
Jordy Roseb6a40262010-08-05 23:11:30 +0000267 BufStart = SV.EvalCast(BufVal, PtrTy, SecondBuf->getType());
268 if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
269 SVal BufEnd = SV.EvalBinOpLN(state, BinaryOperator::Add, *BufLoc,
270 LastOffset, PtrTy);
271 state = CheckLocation(C, state, SecondBuf, BufEnd);
272 }
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000273 }
274
275 // Large enough or not, return this state!
276 return state;
277}
278
279const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
280 const GRState *state,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000281 const Expr *Size,
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000282 const Expr *First,
Jordy Rosed325ffb2010-07-08 23:57:29 +0000283 const Expr *Second) {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000284 // Do a simple check for overlap: if the two arguments are from the same
285 // buffer, see if the end of the first is greater than the start of the second
286 // or vice versa.
287
Jordy Rosed325ffb2010-07-08 23:57:29 +0000288 // If a previous check has failed, propagate the failure.
289 if (!state)
290 return NULL;
291
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000292 ValueManager &VM = state->getStateManager().getValueManager();
293 SValuator &SV = VM.getSValuator();
294 ASTContext &Ctx = VM.getContext();
295 const GRState *stateTrue, *stateFalse;
296
297 // Get the buffer values and make sure they're known locations.
298 SVal FirstVal = state->getSVal(First);
299 SVal SecondVal = state->getSVal(Second);
300
301 Loc *FirstLoc = dyn_cast<Loc>(&FirstVal);
302 if (!FirstLoc)
303 return state;
304
305 Loc *SecondLoc = dyn_cast<Loc>(&SecondVal);
306 if (!SecondLoc)
307 return state;
308
309 // Are the two values the same?
310 DefinedOrUnknownSVal EqualTest = SV.EvalEQ(state, *FirstLoc, *SecondLoc);
311 llvm::tie(stateTrue, stateFalse) = state->Assume(EqualTest);
312
313 if (stateTrue && !stateFalse) {
314 // If the values are known to be equal, that's automatically an overlap.
315 EmitOverlapBug(C, stateTrue, First, Second);
316 return NULL;
317 }
318
319 // Assume the two expressions are not equal.
320 assert(stateFalse);
321 state = stateFalse;
322
323 // Which value comes first?
324 QualType CmpTy = Ctx.IntTy;
325 SVal Reverse = SV.EvalBinOpLL(state, BinaryOperator::GT,
326 *FirstLoc, *SecondLoc, CmpTy);
327 DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse);
328 if (!ReverseTest)
329 return state;
330
331 llvm::tie(stateTrue, stateFalse) = state->Assume(*ReverseTest);
332
333 if (stateTrue) {
334 if (stateFalse) {
335 // If we don't know which one comes first, we can't perform this test.
336 return state;
337 } else {
338 // Switch the values so that FirstVal is before SecondVal.
339 Loc *tmpLoc = FirstLoc;
340 FirstLoc = SecondLoc;
341 SecondLoc = tmpLoc;
342
343 // Switch the Exprs as well, so that they still correspond.
344 const Expr *tmpExpr = First;
345 First = Second;
346 Second = tmpExpr;
347 }
348 }
349
350 // Get the length, and make sure it too is known.
351 SVal LengthVal = state->getSVal(Size);
352 NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
353 if (!Length)
354 return state;
355
356 // Convert the first buffer's start address to char*.
357 // Bail out if the cast fails.
358 QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
359 SVal FirstStart = SV.EvalCast(*FirstLoc, CharPtrTy, First->getType());
360 Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
361 if (!FirstStartLoc)
362 return state;
363
364 // Compute the end of the first buffer. Bail out if THAT fails.
365 SVal FirstEnd = SV.EvalBinOpLN(state, BinaryOperator::Add,
366 *FirstStartLoc, *Length, CharPtrTy);
367 Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
368 if (!FirstEndLoc)
369 return state;
370
371 // Is the end of the first buffer past the start of the second buffer?
372 SVal Overlap = SV.EvalBinOpLL(state, BinaryOperator::GT,
373 *FirstEndLoc, *SecondLoc, CmpTy);
374 DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
375 if (!OverlapTest)
376 return state;
377
378 llvm::tie(stateTrue, stateFalse) = state->Assume(*OverlapTest);
379
380 if (stateTrue && !stateFalse) {
381 // Overlap!
382 EmitOverlapBug(C, stateTrue, First, Second);
383 return NULL;
384 }
385
386 // Assume the two expressions don't overlap.
387 assert(stateFalse);
388 return stateFalse;
389}
390
391void CStringChecker::EmitOverlapBug(CheckerContext &C, const GRState *state,
392 const Stmt *First, const Stmt *Second) {
393 ExplodedNode *N = C.GenerateSink(state);
394 if (!N)
395 return;
396
397 if (!BT_Overlap)
398 BT_Overlap = new BugType("Unix API", "Improper arguments");
399
400 // Generate a report for this bug.
401 RangedBugReport *report =
402 new RangedBugReport(*BT_Overlap,
403 "Arguments must not be overlapping buffers", N);
404 report->addRange(First->getSourceRange());
405 report->addRange(Second->getSourceRange());
406
407 C.EmitReport(report);
408}
409
Jordy Rosea5261542010-08-14 21:02:52 +0000410SVal CStringChecker::GetCStringLengthForRegion(CheckerContext &C,
411 const GRState *&state,
412 const Expr *Ex,
413 const MemRegion *MR) {
414 // If there's a recorded length, go ahead and return it.
415 const SVal *Recorded = state->get<CStringLength>(MR);
416 if (Recorded)
417 return *Recorded;
418
419 // Otherwise, get a new symbol and update the state.
420 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
421 ValueManager &ValMgr = C.getValueManager();
422 QualType SizeTy = ValMgr.getContext().getSizeType();
423 SVal Strlen = ValMgr.getMetadataSymbolVal(getTag(), MR, Ex, SizeTy, Count);
424
425 state = state->set<CStringLength>(MR, Strlen);
426 return Strlen;
427}
428
429SVal CStringChecker::GetCStringLength(CheckerContext &C, const GRState *&state,
Jordy Rose19c5dd12010-07-27 01:37:31 +0000430 const Expr *Ex, SVal Buf) {
431 const MemRegion *MR = Buf.getAsRegion();
432 if (!MR) {
433 // If we can't get a region, see if it's something we /know/ isn't a
434 // C string. In the context of locations, the only time we can issue such
435 // a warning is for labels.
436 if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
Jordy Rosea5261542010-08-14 21:02:52 +0000437 if (ExplodedNode *N = C.GenerateNode(state)) {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000438 if (!BT_NotCString)
439 BT_NotCString = new BuiltinBug("API",
440 "Argument is not a null-terminated string.");
441
442 llvm::SmallString<120> buf;
443 llvm::raw_svector_ostream os(buf);
444 os << "Argument to byte string function is the address of the label '"
445 << Label->getLabel()->getID()->getName()
446 << "', which is not a null-terminated string";
447
448 // Generate a report for this bug.
449 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
450 os.str(), N);
451
452 report->addRange(Ex->getSourceRange());
453 C.EmitReport(report);
454 }
455
456 return UndefinedVal();
457 }
458
Jordy Rosea5261542010-08-14 21:02:52 +0000459 // If it's not a region and not a label, give up.
460 return UnknownVal();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000461 }
462
Jordy Rosea5261542010-08-14 21:02:52 +0000463 // If we have a region, strip casts from it and see if we can figure out
464 // its length. For anything we can't figure out, just return UnknownVal.
465 MR = MR->StripCasts();
466
467 switch (MR->getKind()) {
468 case MemRegion::StringRegionKind: {
469 // Modifying the contents of string regions is undefined [C99 6.4.5p6],
470 // so we can assume that the byte length is the correct C string length.
471 ValueManager &ValMgr = C.getValueManager();
472 QualType SizeTy = ValMgr.getContext().getSizeType();
473 const StringLiteral *Str = cast<StringRegion>(MR)->getStringLiteral();
474 return ValMgr.makeIntVal(Str->getByteLength(), SizeTy);
475 }
476 case MemRegion::SymbolicRegionKind:
477 case MemRegion::AllocaRegionKind:
478 case MemRegion::VarRegionKind:
479 case MemRegion::FieldRegionKind:
480 case MemRegion::ObjCIvarRegionKind:
481 return GetCStringLengthForRegion(C, state, Ex, MR);
482 case MemRegion::CompoundLiteralRegionKind:
483 // FIXME: Can we track this? Is it necessary?
484 return UnknownVal();
485 case MemRegion::ElementRegionKind:
486 // FIXME: How can we handle this? It's not good enough to subtract the
487 // offset from the base string length; consider "123\x00567" and &a[5].
488 return UnknownVal();
489 default:
490 // Other regions (mostly non-data) can't have a reliable C string length.
491 // In this case, an error is emitted and UndefinedVal is returned.
492 // The caller should always be prepared to handle this case.
493 if (ExplodedNode *N = C.GenerateNode(state)) {
494 if (!BT_NotCString)
495 BT_NotCString = new BuiltinBug("API",
496 "Argument is not a null-terminated string.");
497
498 llvm::SmallString<120> buf;
499 llvm::raw_svector_ostream os(buf);
500
501 os << "Argument to byte string function is ";
502
503 if (SummarizeRegion(os, C.getASTContext(), MR))
504 os << ", which is not a null-terminated string";
505 else
506 os << "not a null-terminated string";
507
508 // Generate a report for this bug.
509 EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
510 os.str(), N);
511
512 report->addRange(Ex->getSourceRange());
513 C.EmitReport(report);
514 }
515
516 return UndefinedVal();
517 }
Jordy Rose19c5dd12010-07-27 01:37:31 +0000518}
519
520bool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
521 const MemRegion *MR) {
522 const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
523 if (!TR)
524 return false;
525
526 switch (TR->getKind()) {
527 case MemRegion::FunctionTextRegionKind: {
528 const FunctionDecl *FD = cast<FunctionTextRegion>(TR)->getDecl();
529 if (FD)
530 os << "the address of the function '" << FD << "'";
531 else
532 os << "the address of a function";
533 return true;
534 }
535 case MemRegion::BlockTextRegionKind:
536 os << "block text";
537 return true;
538 case MemRegion::BlockDataRegionKind:
539 os << "a block";
540 return true;
541 case MemRegion::CXXThisRegionKind:
542 case MemRegion::CXXObjectRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000543 os << "a C++ object of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000544 return true;
545 case MemRegion::VarRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000546 os << "a variable of type" << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000547 return true;
548 case MemRegion::FieldRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000549 os << "a field of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000550 return true;
551 case MemRegion::ObjCIvarRegionKind:
Zhongxing Xu018220c2010-08-11 06:10:55 +0000552 os << "an instance variable of type " << TR->getValueType().getAsString();
Jordy Rose19c5dd12010-07-27 01:37:31 +0000553 return true;
554 default:
555 return false;
556 }
557}
558
Jordy Rosed325ffb2010-07-08 23:57:29 +0000559//===----------------------------------------------------------------------===//
560// Evaluation of individual function calls.
561//===----------------------------------------------------------------------===//
562
563void CStringChecker::EvalCopyCommon(CheckerContext &C, const GRState *state,
564 const Expr *Size, const Expr *Dest,
565 const Expr *Source, bool Restricted) {
566 // See if the size argument is zero.
567 SVal SizeVal = state->getSVal(Size);
568 QualType SizeTy = Size->getType();
569
570 const GRState *StZeroSize, *StNonZeroSize;
571 llvm::tie(StZeroSize, StNonZeroSize) = AssumeZero(C, state, SizeVal, SizeTy);
572
573 // If the size is zero, there won't be any actual memory access.
574 if (StZeroSize)
575 C.addTransition(StZeroSize);
576
577 // If the size can be nonzero, we have to check the other arguments.
578 if (StNonZeroSize) {
579 state = StNonZeroSize;
580 state = CheckBufferAccess(C, state, Size, Dest, Source);
581 if (Restricted)
582 state = CheckOverlap(C, state, Size, Dest, Source);
583 if (state)
584 C.addTransition(state);
585 }
586}
587
588
589void CStringChecker::EvalMemcpy(CheckerContext &C, const CallExpr *CE) {
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000590 // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000591 // The return value is the address of the destination buffer.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000592 const Expr *Dest = CE->getArg(0);
593 const GRState *state = C.getState();
594 state = state->BindExpr(CE, state->getSVal(Dest));
595 EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1), true);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000596}
597
Jordy Rosed325ffb2010-07-08 23:57:29 +0000598void CStringChecker::EvalMemmove(CheckerContext &C, const CallExpr *CE) {
599 // void *memmove(void *dst, const void *src, size_t n);
600 // The return value is the address of the destination buffer.
601 const Expr *Dest = CE->getArg(0);
602 const GRState *state = C.getState();
603 state = state->BindExpr(CE, state->getSVal(Dest));
604 EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1));
605}
606
607void CStringChecker::EvalBcopy(CheckerContext &C, const CallExpr *CE) {
608 // void bcopy(const void *src, void *dst, size_t n);
609 EvalCopyCommon(C, C.getState(), CE->getArg(2), CE->getArg(1), CE->getArg(0));
610}
611
612void CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000613 // int memcmp(const void *s1, const void *s2, size_t n);
614 const Expr *Left = CE->getArg(0);
615 const Expr *Right = CE->getArg(1);
616 const Expr *Size = CE->getArg(2);
617
618 const GRState *state = C.getState();
619 ValueManager &ValMgr = C.getValueManager();
620 SValuator &SV = ValMgr.getSValuator();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000621
Jordy Rosed325ffb2010-07-08 23:57:29 +0000622 // See if the size argument is zero.
623 SVal SizeVal = state->getSVal(Size);
624 QualType SizeTy = Size->getType();
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000625
Jordy Rosed325ffb2010-07-08 23:57:29 +0000626 const GRState *StZeroSize, *StNonZeroSize;
627 llvm::tie(StZeroSize, StNonZeroSize) = AssumeZero(C, state, SizeVal, SizeTy);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000628
Jordy Rosed325ffb2010-07-08 23:57:29 +0000629 // If the size can be zero, the result will be 0 in that case, and we don't
630 // have to check either of the buffers.
631 if (StZeroSize) {
632 state = StZeroSize;
633 state = state->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
634 C.addTransition(state);
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000635 }
636
Jordy Rosed325ffb2010-07-08 23:57:29 +0000637 // If the size can be nonzero, we have to check the other arguments.
638 if (StNonZeroSize) {
639 state = StNonZeroSize;
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000640
Jordy Rosed325ffb2010-07-08 23:57:29 +0000641 // If we know the two buffers are the same, we know the result is 0.
642 // First, get the two buffers' addresses. Another checker will have already
643 // made sure they're not undefined.
644 DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
645 DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000646
Jordy Rosed325ffb2010-07-08 23:57:29 +0000647 // See if they are the same.
648 DefinedOrUnknownSVal SameBuf = SV.EvalEQ(state, LV, RV);
649 const GRState *StSameBuf, *StNotSameBuf;
650 llvm::tie(StSameBuf, StNotSameBuf) = state->Assume(SameBuf);
651
652 // If the two arguments might be the same buffer, we know the result is zero,
653 // and we only need to check one size.
654 if (StSameBuf) {
655 state = StSameBuf;
656 state = CheckBufferAccess(C, state, Size, Left);
657 if (state) {
658 state = StSameBuf->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
659 C.addTransition(state);
660 }
661 }
662
663 // If the two arguments might be different buffers, we have to check the
664 // size of both of them.
665 if (StNotSameBuf) {
666 state = StNotSameBuf;
667 state = CheckBufferAccess(C, state, Size, Left, Right);
668 if (state) {
669 // The return value is the comparison result, which we don't know.
670 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
671 SVal CmpV = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
672 state = state->BindExpr(CE, CmpV);
673 C.addTransition(state);
674 }
675 }
676 }
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000677}
678
Jordy Rose19c5dd12010-07-27 01:37:31 +0000679void CStringChecker::EvalStrlen(CheckerContext &C, const CallExpr *CE) {
680 // size_t strlen(const char *s);
681 const GRState *state = C.getState();
682 const Expr *Arg = CE->getArg(0);
683 SVal ArgVal = state->getSVal(Arg);
684
685 // Check that the argument is non-null.
686 state = CheckNonNull(C, state, Arg, ArgVal);
687
688 if (state) {
Jordy Rose19c5dd12010-07-27 01:37:31 +0000689 SVal StrLen = GetCStringLength(C, state, Arg, ArgVal);
Jordy Rosea5261542010-08-14 21:02:52 +0000690
691 // If the argument isn't a valid C string, there's no valid state to
692 // transition to.
693 if (StrLen.isUndef())
694 return;
695
696 // If GetCStringLength couldn't figure out the length, conjure a return
697 // value, so it can be used in constraints, at least.
698 if (StrLen.isUnknown()) {
699 ValueManager &ValMgr = C.getValueManager();
700 unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
701 StrLen = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000702 }
Jordy Rosea5261542010-08-14 21:02:52 +0000703
704 // Bind the return value.
705 state = state->BindExpr(CE, StrLen);
706 C.addTransition(state);
Jordy Rose19c5dd12010-07-27 01:37:31 +0000707 }
708}
709
Jordy Rosed325ffb2010-07-08 23:57:29 +0000710//===----------------------------------------------------------------------===//
Jordy Rosea5261542010-08-14 21:02:52 +0000711// The driver method, and other Checker callbacks.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000712//===----------------------------------------------------------------------===//
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000713
714bool CStringChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
715 // Get the callee. All the functions we care about are C functions
716 // with simple identifiers.
717 const GRState *state = C.getState();
718 const Expr *Callee = CE->getCallee();
719 const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
720
721 if (!FD)
722 return false;
723
724 // Get the name of the callee. If it's a builtin, strip off the prefix.
725 llvm::StringRef Name = FD->getName();
726 if (Name.startswith("__builtin_"))
727 Name = Name.substr(10);
728
729 FnCheck EvalFunction = llvm::StringSwitch<FnCheck>(Name)
Jordy Rosea6b808c2010-07-07 07:48:06 +0000730 .Cases("memcpy", "__memcpy_chk", &CStringChecker::EvalMemcpy)
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000731 .Cases("memcmp", "bcmp", &CStringChecker::EvalMemcmp)
Jordy Rosea6b808c2010-07-07 07:48:06 +0000732 .Cases("memmove", "__memmove_chk", &CStringChecker::EvalMemmove)
Jordy Rose19c5dd12010-07-27 01:37:31 +0000733 .Case("strlen", &CStringChecker::EvalStrlen)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000734 .Case("bcopy", &CStringChecker::EvalBcopy)
735 .Default(NULL);
736
Jordy Rosed325ffb2010-07-08 23:57:29 +0000737 // If the callee isn't a string function, let another checker handle it.
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000738 if (!EvalFunction)
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000739 return false;
740
Jordy Rosed325ffb2010-07-08 23:57:29 +0000741 // Check and evaluate the call.
742 (this->*EvalFunction)(C, CE);
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000743 return true;
744}
Jordy Rosea5261542010-08-14 21:02:52 +0000745
746void CStringChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
747 // Record string length for char a[] = "abc";
748 const GRState *state = C.getState();
749
750 for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
751 I != E; ++I) {
752 const VarDecl *D = dyn_cast<VarDecl>(*I);
753 if (!D)
754 continue;
755
756 // FIXME: Handle array fields of structs.
757 if (!D->getType()->isArrayType())
758 continue;
759
760 const Expr *Init = D->getInit();
761 if (!Init)
762 continue;
763 if (!isa<StringLiteral>(Init))
764 continue;
765
766 Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
767 const MemRegion *MR = VarLoc.getAsRegion();
768 if (!MR)
769 continue;
770
771 SVal StrVal = state->getSVal(Init);
772 assert(StrVal.isValid() && "Initializer string is unknown or undefined");
773 DefinedOrUnknownSVal StrLen
774 = cast<DefinedOrUnknownSVal>(GetCStringLength(C, state, Init, StrVal));
775
776 state = state->set<CStringLength>(MR, StrLen);
777 }
778
779 C.addTransition(state);
780}
781
782bool CStringChecker::WantsRegionChangeUpdate(const GRState *state) {
783 CStringLength::EntryMap Entries = state->get<CStringLength>();
784 return !Entries.isEmpty();
785}
786
787const GRState *CStringChecker::EvalRegionChanges(const GRState *state,
788 const MemRegion * const *Begin,
789 const MemRegion * const *End,
790 bool *) {
791 CStringLength::EntryMap Entries = state->get<CStringLength>();
792 if (Entries.isEmpty())
793 return state;
794
795 llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
796 llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
797
798 // First build sets for the changed regions and their super-regions.
799 for ( ; Begin != End; ++Begin) {
800 const MemRegion *MR = *Begin;
801 Invalidated.insert(MR);
802
803 SuperRegions.insert(MR);
804 while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
805 MR = SR->getSuperRegion();
806 SuperRegions.insert(MR);
807 }
808 }
809
810 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
811
812 // Then loop over the entries in the current state.
813 for (CStringLength::EntryMap::iterator I = Entries.begin(),
814 E = Entries.end(); I != E; ++I) {
815 const MemRegion *MR = I.getKey();
816
817 // Is this entry for a super-region of a changed region?
818 if (SuperRegions.count(MR)) {
819 Entries = F.Remove(Entries, MR);
820 continue;
821 }
822
823 // Is this entry for a sub-region of a changed region?
824 const MemRegion *Super = MR;
825 while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
826 Super = SR->getSuperRegion();
827 if (Invalidated.count(Super)) {
828 Entries = F.Remove(Entries, MR);
829 break;
830 }
831 }
832 }
833
834 return state->set<CStringLength>(Entries);
835}
836
837void CStringChecker::MarkLiveSymbols(const GRState *state, SymbolReaper &SR) {
838 // Mark all symbols in our string length map as valid.
839 CStringLength::EntryMap Entries = state->get<CStringLength>();
840
841 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
842 I != E; ++I) {
843 SVal Len = I.getData();
844 if (SymbolRef Sym = Len.getAsSymbol())
845 SR.markInUse(Sym);
846 }
847}
848
849void CStringChecker::EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR) {
850 if (!SR.hasDeadSymbols())
851 return;
852
853 const GRState *state = C.getState();
854 CStringLength::EntryMap Entries = state->get<CStringLength>();
855 if (Entries.isEmpty())
856 return;
857
858 CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
859 for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
860 I != E; ++I) {
861 SVal Len = I.getData();
862 if (SymbolRef Sym = Len.getAsSymbol()) {
863 if (SR.isDead(Sym))
864 Entries = F.Remove(Entries, I.getKey());
865 }
866 }
867
868 state = state->set<CStringLength>(Entries);
869 C.GenerateNode(state);
870}