Lines Matching defs:C
1 //= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-//
114 bool evalCall(const CallEvent &Call, CheckerContext &C) const;
115 void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
117 void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
199 FnCheck identifyCall(const CallEvent &Call, CheckerContext &C) const;
200 void evalMemcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const;
201 void evalMempcpy(CheckerContext &C, const CallEvent &Call, CharKind CK) const;
202 void evalMemmove(CheckerContext &C, const CallEvent &Call, CharKind CK) const;
203 void evalBcopy(CheckerContext &C, const CallEvent &Call) const;
204 void evalCopyCommon(CheckerContext &C, const CallEvent &Call,
209 void evalMemcmp(CheckerContext &C, const CallEvent &Call, CharKind CK) const;
211 void evalstrLength(CheckerContext &C, const CallEvent &Call) const;
212 void evalstrnLength(CheckerContext &C, const CallEvent &Call) const;
213 void evalstrLengthCommon(CheckerContext &C, const CallEvent &Call,
216 void evalStrcpy(CheckerContext &C, const CallEvent &Call) const;
217 void evalStrncpy(CheckerContext &C, const CallEvent &Call) const;
218 void evalStpcpy(CheckerContext &C, const CallEvent &Call) const;
219 void evalStrlcpy(CheckerContext &C, const CallEvent &Call) const;
220 void evalStrcpyCommon(CheckerContext &C, const CallEvent &Call,
224 void evalStrcat(CheckerContext &C, const CallEvent &Call) const;
225 void evalStrncat(CheckerContext &C, const CallEvent &Call) const;
226 void evalStrlcat(CheckerContext &C, const CallEvent &Call) const;
228 void evalStrcmp(CheckerContext &C, const CallEvent &Call) const;
229 void evalStrncmp(CheckerContext &C, const CallEvent &Call) const;
230 void evalStrcasecmp(CheckerContext &C, const CallEvent &Call) const;
231 void evalStrncasecmp(CheckerContext &C, const CallEvent &Call) const;
232 void evalStrcmpCommon(CheckerContext &C, const CallEvent &Call,
235 void evalStrsep(CheckerContext &C, const CallEvent &Call) const;
237 void evalStdCopy(CheckerContext &C, const CallEvent &Call) const;
238 void evalStdCopyBackward(CheckerContext &C, const CallEvent &Call) const;
239 void evalStdCopyCommon(CheckerContext &C, const CallEvent &Call) const;
240 void evalMemset(CheckerContext &C, const CallEvent &Call) const;
241 void evalBzero(CheckerContext &C, const CallEvent &Call) const;
243 void evalSprintf(CheckerContext &C, const CallEvent &Call) const;
244 void evalSnprintf(CheckerContext &C, const CallEvent &Call) const;
245 void evalSprintfCommon(CheckerContext &C, const CallEvent &Call,
250 static assumeZero(CheckerContext &C,
256 static SVal getCStringLengthForRegion(CheckerContext &C,
261 SVal getCStringLength(CheckerContext &C,
267 const StringLiteral *getCStringLiteral(CheckerContext &C,
274 invalidateDestinationBufferBySize(CheckerContext &C, ProgramStateRef S,
280 CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV);
285 CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV);
288 static ProgramStateRef invalidateSourceBuffer(CheckerContext &C,
296 CheckerContext &C, ProgramStateRef State, const Expr *Ex, SVal V,
305 const Expr *Size, CheckerContext &C,
309 ProgramStateRef checkNonNull(CheckerContext &C, ProgramStateRef State,
313 ProgramStateRef checkInit(CheckerContext &C, ProgramStateRef state,
315 ProgramStateRef CheckLocation(CheckerContext &C, ProgramStateRef state,
319 ProgramStateRef CheckBufferAccess(CheckerContext &C, ProgramStateRef State,
323 ProgramStateRef CheckOverlap(CheckerContext &C, ProgramStateRef state,
327 void emitOverlapBug(CheckerContext &C,
332 void emitNullArgBug(CheckerContext &C, ProgramStateRef State, const Stmt *S,
334 void emitOutOfBoundsBug(CheckerContext &C, ProgramStateRef State,
336 void emitNotCStringBug(CheckerContext &C, ProgramStateRef State,
338 void emitAdditionOverflowBug(CheckerContext &C, ProgramStateRef State) const;
339 void emitUninitializedReadBug(CheckerContext &C, ProgramStateRef State,
341 ProgramStateRef checkAdditionOverflow(CheckerContext &C,
349 static bool isFirstBufInBound(CheckerContext &C, ProgramStateRef State,
363 CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef State, SVal V,
369 SValBuilder &svalBuilder = C.getSValBuilder();
374 ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
383 assumeZero(C, State, l, Arg.Expression->getType());
394 emitNullArgBug(C, stateNull, Arg.Expression, OS.str());
435 ProgramStateRef CStringChecker::checkInit(CheckerContext &C,
458 SValBuilder &SVB = C.getSValBuilder();
477 emitUninitializedReadBug(C, State, Buffer.Expression, OS.str());
531 C.addSink();
541 emitUninitializedReadBug(C, State, Buffer.Expression, OS.str());
548 ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
575 getDynamicExtent(state, superReg, C.getSValBuilder());
588 emitOutOfBoundsBug(C, StOutBound, Buffer.Expression, Message);
598 CStringChecker::CheckBufferAccess(CheckerContext &C, ProgramStateRef State,
605 SValBuilder &svalBuilder = C.getSValBuilder();
612 SVal BufVal = C.getSVal(Buffer.Expression);
613 State = checkNonNull(C, State, Buffer, BufVal);
625 State = CheckLocation(C, State, Buffer, BufStart, Access, CK);
633 SVal LengthVal = C.getSVal(Size.Expression);
650 State = CheckLocation(C, State, Buffer, BufEnd, Access, CK);
652 State = checkInit(C, State, Buffer, BufEnd, *Length);
663 ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
687 const LocationContext *LCtx = C.getLocationContext();
700 SValBuilder &svalBuilder = C.getSValBuilder();
706 emitOverlapBug(C, stateTrue, First.Expression, Second.Expression);
772 emitOverlapBug(C, stateTrue, First.Expression, Second.Expression);
781 void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state,
783 ExplodedNode *N = C.generateErrorNode(state);
797 C.emitReport(std::move(report));
800 void CStringChecker::emitNullArgBug(CheckerContext &C, ProgramStateRef State,
802 if (ExplodedNode *N = C.generateErrorNode(State)) {
815 C.emitReport(std::move(Report));
819 void CStringChecker::emitUninitializedReadBug(CheckerContext &C,
823 if (ExplodedNode *N = C.generateErrorNode(State)) {
834 C.emitReport(std::move(Report));
838 void CStringChecker::emitOutOfBoundsBug(CheckerContext &C,
841 if (ExplodedNode *N = C.generateErrorNode(State)) {
854 C.emitReport(std::move(Report));
858 void CStringChecker::emitNotCStringBug(CheckerContext &C, ProgramStateRef State,
861 if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) {
873 C.emitReport(std::move(Report));
877 void CStringChecker::emitAdditionOverflowBug(CheckerContext &C,
879 if (ExplodedNode *N = C.generateErrorNode(State)) {
897 C.emitReport(std::move(Report));
901 ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
913 SValBuilder &svalBuilder = C.getSValBuilder();
944 emitAdditionOverflowBug(C, stateOverflow);
984 // Other regions (mostly non-data) can't have a reliable C string length.
997 SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
1010 SValBuilder &svalBuilder = C.getSValBuilder();
1014 C.getLocationContext(),
1015 C.blockCount());
1036 SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
1042 // C string. In the context of locations, the only time we can issue such
1053 emitNotCStringBug(C, state, Ex, os.str());
1069 // so we can assume that the byte length is the correct C string length.
1070 SValBuilder &svalBuilder = C.getSValBuilder();
1082 SValBuilder &SvalBuilder = C.getSValBuilder();
1095 return getCStringLengthForRegion(C, state, Ex, MR, hypothetical);
1104 // Other regions (mostly non-data) can't have a reliable C string length.
1114 if (SummarizeRegion(os, C.getASTContext(), MR))
1119 emitNotCStringBug(C, state, Ex, os.str());
1125 const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
1145 bool CStringChecker::isFirstBufInBound(CheckerContext &C, ProgramStateRef State,
1156 SValBuilder &SB = C.getSValBuilder();
1157 ASTContext &Ctx = C.getASTContext();
1191 assert(ER->getValueType() == C.getASTContext().CharTy &&
1207 CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV,
1210 [&C, S, BufTy = BufE->getType(), BufV, SizeV,
1215 isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy)) {
1223 return invalidateBufferAux(C, S, BufE, BufV, InvalidationTraitOperations);
1228 CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV) {
1234 return invalidateBufferAux(C, S, BufE, BufV, InvalidationTraitOperations);
1238 CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV) {
1248 return invalidateBufferAux(C, S, BufE, BufV, InvalidationTraitOperations);
1251 ProgramStateRef CStringChecker::invalidateSourceBuffer(CheckerContext &C,
1265 return invalidateBufferAux(C, S, BufE, BufV, InvalidationTraitOperations);
1269 CheckerContext &C, ProgramStateRef State, const Expr *E, SVal V,
1291 const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
1295 return State->invalidateRegions(R, E, C.blockCount(), LCtx,
1324 os << "a C++ temp object of type "
1346 const Expr *Size, CheckerContext &C,
1348 SVal MemVal = C.getSVal(DstBuffer);
1349 SVal SizeVal = C.getSVal(Size);
1365 SValBuilder &svalBuilder = C.getSValBuilder();
1366 ASTContext &Ctx = C.getASTContext();
1385 assumeZero(C, State, CharVal, Ctx.UnsignedCharTy);
1396 C.getLocationContext());
1400 State = invalidateDestinationBufferBySize(C, State, DstBuffer, MemVal,
1412 C.getLocationContext(), C.blockCount());
1426 State = invalidateDestinationBufferBySize(C, State, DstBuffer, MemVal,
1436 void CStringChecker::evalCopyCommon(CheckerContext &C, const CallEvent &Call,
1444 const LocationContext *LCtx = C.getLocationContext();
1450 assumeZero(C, state, sizeVal, sizeTy);
1460 C.addTransition(stateZeroSize);
1473 state = checkNonNull(C, state, Dest, destVal);
1482 state = checkNonNull(C, state, Source, srcVal);
1487 state = CheckBufferAccess(C, state, Dest, Size, AccessKind::write, CK);
1488 state = CheckBufferAccess(C, state, Source, Size, AccessKind::read, CK);
1491 state = CheckOverlap(C, state, Size, Dest, Source, CK);
1500 SValBuilder &SvalBuilder = C.getSValBuilder();
1505 SVal lastElement = C.getSValBuilder().evalBinOp(
1510 lastElement = C.getSValBuilder().conjureSymbolVal(
1511 nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1528 C, state, Dest.Expression, C.getSVal(Dest.Expression), sizeVal,
1533 state = invalidateSourceBuffer(C, state, Source.Expression,
1534 C.getSVal(Source.Expression));
1536 C.addTransition(state);
1540 void CStringChecker::evalMemcpy(CheckerContext &C, const CallEvent &Call,
1548 ProgramStateRef State = C.getState();
1552 evalCopyCommon(C, Call, State, Size, Dest, Src, IsRestricted, IsMempcpy, CK);
1555 void CStringChecker::evalMempcpy(CheckerContext &C, const CallEvent &Call,
1565 evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted,
1569 void CStringChecker::evalMemmove(CheckerContext &C, const CallEvent &Call,
1579 evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted,
1583 void CStringChecker::evalBcopy(CheckerContext &C, const CallEvent &Call) const {
1591 evalCopyCommon(C, Call, C.getState(), Size, Dest, Src, IsRestricted,
1595 void CStringChecker::evalMemcmp(CheckerContext &C, const CallEvent &Call,
1604 ProgramStateRef State = C.getState();
1605 SValBuilder &Builder = C.getSValBuilder();
1606 const LocationContext *LCtx = C.getLocationContext();
1614 assumeZero(C, State, sizeVal, sizeTy);
1622 C.addTransition(State);
1645 State = CheckBufferAccess(C, State, Left, Size, AccessKind::read);
1649 C.addTransition(State);
1657 State = CheckBufferAccess(C, State, Right, Size, AccessKind::read, CK);
1658 State = CheckBufferAccess(C, State, Left, Size, AccessKind::read, CK);
1662 C.blockCount());
1664 C.addTransition(State);
1669 void CStringChecker::evalstrLength(CheckerContext &C,
1672 evalstrLengthCommon(C, Call, /* IsStrnlen = */ false);
1675 void CStringChecker::evalstrnLength(CheckerContext &C,
1678 evalstrLengthCommon(C, Call, /* IsStrnlen = */ true);
1681 void CStringChecker::evalstrLengthCommon(CheckerContext &C,
1685 ProgramStateRef state = C.getState();
1686 const LocationContext *LCtx = C.getLocationContext();
1694 assumeZero(C, state, maxlenVal, maxlenExpr->getType());
1699 SVal zero = C.getSValBuilder().makeZeroVal(Call.getResultType());
1701 C.addTransition(stateZeroSize);
1715 state = checkNonNull(C, state, Arg, ArgVal);
1720 SVal strLength = getCStringLength(C, state, Arg.Expression, ArgVal);
1722 // If the argument isn't a valid C string, there's no valid state to
1732 QualType cmpTy = C.getSValBuilder().getConditionType();
1747 C.getSValBuilder()
1765 result = C.getSValBuilder().conjureSymbolVal(
1766 nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1770 state = state->assume(C.getSValBuilder().evalBinOpNN(
1776 state = state->assume(C.getSValBuilder().evalBinOpNN(
1789 result = C.getSValBuilder().conjureSymbolVal(
1790 nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1797 C.addTransition(state);
1800 void CStringChecker::evalStrcpy(CheckerContext &C,
1803 evalStrcpyCommon(C, Call,
1809 void CStringChecker::evalStrncpy(CheckerContext &C,
1812 evalStrcpyCommon(C, Call,
1818 void CStringChecker::evalStpcpy(CheckerContext &C,
1821 evalStrcpyCommon(C, Call,
1827 void CStringChecker::evalStrlcpy(CheckerContext &C,
1830 evalStrcpyCommon(C, Call,
1837 void CStringChecker::evalStrcat(CheckerContext &C,
1840 evalStrcpyCommon(C, Call,
1846 void CStringChecker::evalStrncat(CheckerContext &C,
1849 evalStrcpyCommon(C, Call,
1855 void CStringChecker::evalStrlcat(CheckerContext &C,
1860 evalStrcpyCommon(C, Call,
1867 void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call,
1876 ProgramStateRef state = C.getState();
1877 const LocationContext *LCtx = C.getLocationContext();
1882 state = checkNonNull(C, state, Dst, DstVal);
1889 state = checkNonNull(C, state, srcExpr, srcVal);
1894 SVal strLength = getCStringLength(C, state, srcExpr.Expression, srcVal);
1898 SVal dstStrLength = getCStringLength(C, state, Dst.Expression, DstVal);
1901 // If the source isn't a valid C string, give up.
1905 SValBuilder &svalBuilder = C.getSValBuilder();
1921 C, state,
2040 assumeZero(C, state, *lenValNL, sizeTy);
2060 C.addTransition(StateZeroSize);
2113 state = checkAdditionOverflow(C, state, *amountCopiedNL, *dstStrLengthNL);
2127 getCStringLength(C, state, Call.getOriginExpr(), DstVal, true);
2193 state = CheckLocation(C, state, Dst, DstVal, AccessKind::write);
2197 state = CheckLocation(C, state, Dst, maxLastElement, AccessKind::write);
2210 state = CheckLocation(C, state, Dst, DstVal, AccessKind::write);
2214 state = CheckLocation(C, state, Dst, lastElement, AccessKind::write);
2226 // C string length because invalidation will clear the length.
2231 state = invalidateDestinationBufferBySize(C, state, Dst.Expression,
2233 C.getASTContext().getSizeType());
2237 state = invalidateSourceBuffer(C, state, srcExpr.Expression, srcVal);
2239 // Set the C string length of the destination, if we know it.
2258 C.blockCount());
2263 C.addTransition(state);
2266 void CStringChecker::evalStrcmp(CheckerContext &C,
2269 evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ false);
2272 void CStringChecker::evalStrncmp(CheckerContext &C,
2275 evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ false);
2278 void CStringChecker::evalStrcasecmp(CheckerContext &C,
2281 evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ true);
2284 void CStringChecker::evalStrncasecmp(CheckerContext &C,
2287 evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ true);
2290 void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call,
2293 ProgramStateRef state = C.getState();
2294 const LocationContext *LCtx = C.getLocationContext();
2299 state = checkNonNull(C, state, Left, LeftVal);
2306 state = checkNonNull(C, state, Right, RightVal);
2311 SVal LeftLength = getCStringLength(C, state, Left.Expression, LeftVal);
2316 SVal RightLength = getCStringLength(C, state, Right.Expression, RightVal);
2327 SValBuilder &svalBuilder = C.getSValBuilder();
2338 C.addTransition(StSameBuf);
2353 getCStringLiteral(C, state, Left.Expression, LeftVal);
2355 getCStringLiteral(C, state, Right.Expression, RightVal);
2358 LCtx, C.blockCount());
2417 C.addTransition(state);
2420 void CStringChecker::evalStrsep(CheckerContext &C,
2432 ProgramStateRef State = C.getState();
2433 const LocationContext *LCtx = C.getLocationContext();
2438 State = checkNonNull(C, State, SearchStrPtr, SearchStrVal);
2445 State = checkNonNull(C, State, DelimStr, DelimStrVal);
2449 SValBuilder &SVB = C.getSValBuilder();
2459 C, State, SearchStrPtr.Expression, Result);
2466 LCtx, CharPtrTy, C.blockCount()),
2472 C.blockCount());
2477 C.addTransition(State);
2480 // These should probably be moved into a C++ standard library checker.
2481 void CStringChecker::evalStdCopy(CheckerContext &C,
2483 evalStdCopyCommon(C, Call);
2486 void CStringChecker::evalStdCopyBackward(CheckerContext &C,
2488 evalStdCopyCommon(C, Call);
2491 void CStringChecker::evalStdCopyCommon(CheckerContext &C,
2496 ProgramStateRef State = C.getState();
2498 const LocationContext *LCtx = C.getLocationContext();
2511 invalidateDestinationBufferAlwaysEscapeSuperRegion(C, State, Dst, DstVal);
2513 SValBuilder &SVB = C.getSValBuilder();
2516 SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
2519 C.addTransition(State);
2522 void CStringChecker::evalMemset(CheckerContext &C,
2531 ProgramStateRef State = C.getState();
2534 const LocationContext *LCtx = C.getLocationContext();
2535 SVal SizeVal = C.getSVal(Size.Expression);
2539 std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy);
2542 SVal BufferPtrVal = C.getSVal(Buffer.Expression);
2548 C.addTransition(ZeroSize);
2554 State = checkNonNull(C, NonZeroSize, Buffer, BufferPtrVal);
2558 State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write);
2565 if (!memsetAux(Buffer.Expression, C.getSVal(CharE.Expression),
2566 Size.Expression, C, State))
2570 C.addTransition(State);
2573 void CStringChecker::evalBzero(CheckerContext &C, const CallEvent &Call) const {
2578 SVal Zero = C.getSValBuilder().makeZeroVal(C.getASTContext().IntTy);
2580 ProgramStateRef State = C.getState();
2583 SVal SizeVal = C.getSVal(Size.Expression);
2588 assumeZero(C, State, SizeVal, SizeTy);
2593 C.addTransition(StateZeroSize);
2598 SVal MemVal = C.getSVal(Buffer.Expression);
2602 State = checkNonNull(C, StateNonZeroSize, Buffer, MemVal);
2606 State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write);
2610 if (!memsetAux(Buffer.Expression, Zero, Size.Expression, C, State))
2613 C.addTransition(State);
2616 void CStringChecker::evalSprintf(CheckerContext &C,
2619 evalSprintfCommon(C, Call, /* IsBounded = */ false);
2622 void CStringChecker::evalSnprintf(CheckerContext &C,
2625 evalSprintfCommon(C, Call, /* IsBounded = */ true);
2628 void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallEvent &Call,
2630 ProgramStateRef State = C.getState();
2656 C, State,
2663 C.addTransition(State);
2671 CheckerContext &C) const {
2687 // into, say, a C++ overload of any of these functions. We could not check
2702 bool CStringChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
2703 FnCheck Callback = identifyCall(Call, C);
2711 Callback(this, C, Call);
2719 return C.isDifferent();
2722 void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
2724 ProgramStateRef state = C.getState();
2741 Loc VarLoc = state->getLValue(D, C.getLocationContext());
2746 SVal StrVal = C.getSVal(Init);
2749 getCStringLength(C, state, Init, StrVal).castAs<DefinedOrUnknownSVal>();
2754 C.addTransition(state);
2818 CheckerContext &C) const {
2819 ProgramStateRef state = C.getState();
2833 C.addTransition(state);