Lines Matching +full:tie +full:- +full:off
1 //= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
65 Os << " accesses out-of-bound array element"; in createOutOfBoundErrorMsg()
308 // Re-usable checks
358 //===----------------------------------------------------------------------===// in REGISTER_MAP_WITH_PROGRAMSTATE()
360 //===----------------------------------------------------------------------===// in REGISTER_MAP_WITH_PROGRAMSTATE()
371 return State->assume(svalBuilder.evalEQ(State, *val, zero)); in REGISTER_MAP_WITH_PROGRAMSTATE()
382 std::tie(stateNull, stateNonNull) = in checkNonNull()
383 assumeZero(C, State, l, Arg.Expression->getType()); in checkNonNull()
399 // From here on, assume that the value is non-null. in checkNonNull()
406 SValBuilder &SVB = State->getStateManager().getSValBuilder(); in getIndex()
410 if (ER->getValueType() != Ctx.CharTy) in getIndex()
412 return ER->getIndex(); in getIndex()
415 if (ER->getValueType() != Ctx.WideCharTy) in getIndex()
424 SVB.evalBinOpNN(State, BO_Mul, ER->getIndex(), WideSize, SizeTy); in getIndex()
430 // Basically 1 -> 1st, 12 -> 12th, etc.
449 const auto *SuperR = ER->getSuperRegion()->getAs<TypedValueRegion>(); in checkInit()
455 if (!SuperR->getValueType()->isArrayType()) in checkInit()
461 const QualType ElemTy = Ctx.getBaseElementType(SuperR->getValueType()); in checkInit()
465 State->getLValue(ElemTy, Zero, loc::MemRegionVal(SuperR)).getAs<Loc>(); in checkInit()
471 State->getSVal(*FirstElementVal).isUndef()) { in checkInit()
481 // We won't check whether the entire region is fully initialized -- lets just in checkInit()
507 // past-the-end element. in checkInit()
521 State->getLValue(ElemTy, LastIdx, loc::MemRegionVal(SuperR)); in checkInit()
526 State->getSVal(LastElementVal.castAs<Loc>()).isUndef()) { in checkInit()
528 // If we can't get emit a sensible last element index, just bail out -- in checkInit()
537 OS << IdxInt->getExtValue(); in checkInit()
573 const auto *superReg = cast<SubRegion>(ER->getSuperRegion()); in CheckLocation()
577 auto [StInBound, StOutBound] = state->assumeInBoundDual(*Idx, Size); in CheckLocation()
579 // These checks are either enabled by the CString out-of-bounds checker in CheckLocation()
608 QualType SizeTy = Size.Expression->getType(); in CheckBufferAccess()
611 // Check that the first buffer is non-null. in CheckBufferAccess()
617 // If out-of-bounds checking is turned off, skip the rest. in CheckBufferAccess()
622 svalBuilder.evalCast(BufVal, PtrTy, Buffer.Expression->getType()); in CheckBufferAccess()
638 // Compute the offset of the last element to be accessed: size-1. in CheckBufferAccess()
682 if (First.Expression->getType()->getPointeeType().getAddressSpace() != in CheckOverlap()
683 Second.Expression->getType()->getPointeeType().getAddressSpace()) in CheckOverlap()
688 SVal firstVal = state->getSVal(First.Expression, LCtx); in CheckOverlap()
689 SVal secondVal = state->getSVal(Second.Expression, LCtx); in CheckOverlap()
701 std::tie(stateTrue, stateFalse) = in CheckOverlap()
702 state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc)); in CheckOverlap()
723 std::tie(stateTrue, stateFalse) = state->assume(*reverseTest); in CheckOverlap()
738 SVal LengthVal = state->getSVal(Size.Expression, LCtx); in CheckOverlap()
748 svalBuilder.evalCast(*firstLoc, CharPtrTy, First.Expression->getType()); in CheckOverlap()
768 std::tie(stateTrue, stateFalse) = state->assume(*OverlapTest); in CheckOverlap()
794 report->addRange(First->getSourceRange()); in emitOverlapBug()
795 report->addRange(Second->getSourceRange()); in emitOverlapBug()
812 Report->addRange(S->getSourceRange()); in emitNullArgBug()
830 Report->addNote("Other elements might also be undefined", in emitUninitializedReadBug()
831 Report->getLocation()); in emitUninitializedReadBug()
832 Report->addRange(E->getSourceRange()); in emitUninitializedReadBug()
846 "Out-of-bound array access")); in emitOutOfBoundsBug()
853 Report->addRange(S->getSourceRange()); in emitOutOfBoundsBug()
872 Report->addRange(S->getSourceRange()); in emitNotCStringBug()
889 // code anyway -- you'd have to create a buffer longer than a size_t can in emitAdditionOverflowBug()
905 // If out-of-bounds checking is turned off, skip the rest. in checkAdditionOverflow()
934 // If left > max - right, we have an overflow. in checkAdditionOverflow()
939 std::tie(stateOverflow, stateOkay) = in checkAdditionOverflow()
940 state->assume(willOverflow.castAs<DefinedOrUnknownSVal>()); in checkAdditionOverflow()
961 MR = MR->StripCasts(); in setCStringLength()
963 switch (MR->getKind()) { in setCStringLength()
979 // FIXME: Handle element regions by upper-bounding the parent region's in setCStringLength()
984 // Other regions (mostly non-data) can't have a reliable C string length. in setCStringLength()
992 return state->remove<CStringLength>(MR); in setCStringLength()
994 return state->set<CStringLength>(MR, strLength); in setCStringLength()
1004 const SVal *Recorded = state->get<CStringLength>(MR); in getCStringLengthForRegion()
1028 state = state->assume(evalLength.castAs<DefinedOrUnknownSVal>(), true); in getCStringLengthForRegion()
1030 state = state->set<CStringLength>(MR, strLength); in getCStringLengthForRegion()
1050 << " is the address of the label '" << Label->getLabel()->getName() in getCStringLength()
1051 << "', which is not a null-terminated string"; in getCStringLength()
1064 MR = MR->StripCasts(); in getCStringLength()
1066 switch (MR->getKind()) { in getCStringLength()
1072 const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral(); in getCStringLength()
1073 return svalBuilder.makeIntVal(strLit->getLength(), sizeTy); in getCStringLength()
1078 const VarDecl *Decl = cast<NonParamVarRegion>(MR)->getDecl(); in getCStringLength()
1079 if (Decl->getType().isConstQualified() && Decl->hasGlobalStorage()) { in getCStringLength()
1080 if (const Expr *Init = Decl->getInit()) { in getCStringLength()
1084 return SvalBuilder.makeIntVal(StrLit->getLength(), SizeTy); in getCStringLength()
1104 // Other regions (mostly non-data) can't have a reliable C string length. in getCStringLength()
1115 os << ", which is not a null-terminated string"; in getCStringLength()
1117 os << "not a null-terminated string"; in getCStringLength()
1133 // Strip casts off the memory region. in getCStringLiteral()
1134 bufRegion = bufRegion->StripCasts(); in getCStringLiteral()
1142 return strRegion->getStringLiteral(); in getCStringLiteral()
1165 // Compute the offset of the last element to be accessed: size-1. in isFirstBufInBound()
1189 // FIXME: Does this crash when a non-standard definition in isFirstBufInBound()
1191 assert(ER->getValueType() == C.getASTContext().CharTy && in isFirstBufInBound()
1195 const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion()); in isFirstBufInBound()
1199 DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>(); in isFirstBufInBound()
1201 ProgramStateRef StInBound = State->assumeInBound(Idx, SizeDV, true); in isFirstBufInBound()
1210 [&C, S, BufTy = BufE->getType(), BufV, SizeV, in invalidateDestinationBufferBySize()
1214 if (MemRegion::FieldRegionKind == R->getKind() && in invalidateDestinationBufferBySize()
1241 if (MemRegion::FieldRegionKind == R->getKind()) in invalidateDestinationBufferNeverOverflows()
1258 R->getBaseRegion(), in invalidateSourceBuffer()
1277 // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes in invalidateBufferAux()
1280 if (std::optional<loc::MemRegionVal> MR = L->getAs<loc::MemRegionVal>()) { in invalidateBufferAux()
1281 const MemRegion *R = MR->getRegion()->StripCasts(); in invalidateBufferAux()
1284 // the super-region. in invalidateBufferAux()
1286 R = ER->getSuperRegion(); in invalidateBufferAux()
1291 const LocationContext *LCtx = C.getPredecessor()->getLocationContext(); in invalidateBufferAux()
1295 return State->invalidateRegions(R, E, C.blockCount(), LCtx, in invalidateBufferAux()
1300 // If we have a non-region value by chance, just remove the binding. in invalidateBufferAux()
1301 // FIXME: is this necessary or correct? This handles the non-Region in invalidateBufferAux()
1303 return State->killBinding(*L); in invalidateBufferAux()
1308 switch (MR->getKind()) { in SummarizeRegion()
1310 if (const auto *FD = cast<FunctionCodeRegion>(MR)->getDecl()) in SummarizeRegion()
1325 << cast<TypedValueRegion>(MR)->getValueType(); in SummarizeRegion()
1328 os << "a variable of type" << cast<TypedValueRegion>(MR)->getValueType(); in SummarizeRegion()
1331 os << "a parameter of type" << cast<TypedValueRegion>(MR)->getValueType(); in SummarizeRegion()
1334 os << "a field of type " << cast<TypedValueRegion>(MR)->getValueType(); in SummarizeRegion()
1338 << cast<TypedValueRegion>(MR)->getValueType(); in SummarizeRegion()
1355 // Our current implementation - RegionStore - doesn't support default bindings in memsetAux()
1358 RegionOffset Offset = MR->getAsOffset(); in memsetAux()
1376 std::tie(StateWholeReg, StateNotWholeReg) = in memsetAux()
1377 State->assume(svalBuilder.evalEQ(State, SizeDV, *SizeNL)); in memsetAux()
1384 std::tie(StateNullChar, StateNonNullChar) = in memsetAux()
1392 // FIXME: Since there is no perfect way to bind the non-zero character, we in memsetAux()
1394 // the binding of non-zero value in the case of whole region. in memsetAux()
1395 State = State->bindDefaultZero(svalBuilder.makeLoc(BR), in memsetAux()
1401 SizeVal, Size->getType()); in memsetAux()
1420 State->assume(NewStrLenGESize.castAs<DefinedOrUnknownSVal>(), true), in memsetAux()
1427 SizeVal, Size->getType()); in memsetAux()
1432 //===----------------------------------------------------------------------===//
1434 //===----------------------------------------------------------------------===//
1445 SVal sizeVal = state->getSVal(Size.Expression, LCtx); in evalCopyCommon()
1446 QualType sizeTy = Size.Expression->getType(); in evalCopyCommon()
1449 std::tie(stateZeroSize, stateNonZeroSize) = in evalCopyCommon()
1453 SVal destVal = state->getSVal(Dest.Expression, LCtx); in evalCopyCommon()
1459 stateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, destVal); in evalCopyCommon()
1478 SVal srcVal = state->getSVal(Source.Expression, LCtx); in evalCopyCommon()
1504 SvalBuilder.evalCast(destVal, CharPtrTy, Dest.Expression->getType()); in evalCopyCommon()
1506 state, BO_Add, DestRegCharVal, sizeVal, Dest.Expression->getType()); in evalCopyCommon()
1514 state = state->BindExpr(Call.getOriginExpr(), LCtx, lastElement); in evalCopyCommon()
1518 state = state->BindExpr(Call.getOriginExpr(), LCtx, destVal); in evalCopyCommon()
1521 // Invalidate the destination (regular invalidation without pointer-escaping in evalCopyCommon()
1522 // the address of the top-level region). in evalCopyCommon()
1529 Size.Expression->getType()); in evalCopyCommon()
1531 // Invalidate the source (const-invalidation without const-pointer-escaping in evalCopyCommon()
1532 // the address of the top-level region). in evalCopyCommon()
1609 SVal sizeVal = State->getSVal(Size.Expression, LCtx); in evalMemcmp()
1610 QualType sizeTy = Size.Expression->getType(); in evalMemcmp()
1613 std::tie(stateZeroSize, stateNonZeroSize) = in evalMemcmp()
1620 State = State->BindExpr(Call.getOriginExpr(), LCtx, in evalMemcmp()
1632 State->getSVal(Left.Expression, LCtx).castAs<DefinedOrUnknownSVal>(); in evalMemcmp()
1634 State->getSVal(Right.Expression, LCtx).castAs<DefinedOrUnknownSVal>(); in evalMemcmp()
1638 std::tie(SameBuffer, NotSameBuffer) = in evalMemcmp()
1639 State->assume(Builder.evalEQ(State, LV, RV)); in evalMemcmp()
1647 State = SameBuffer->BindExpr(Call.getOriginExpr(), LCtx, in evalMemcmp()
1663 State = State->BindExpr(Call.getOriginExpr(), LCtx, CmpV); in evalMemcmp()
1690 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); in evalstrLengthCommon()
1693 std::tie(stateZeroSize, stateNonZeroSize) = in evalstrLengthCommon()
1694 assumeZero(C, state, maxlenVal, maxlenExpr->getType()); in evalstrLengthCommon()
1700 stateZeroSize = stateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, zero); in evalstrLengthCommon()
1712 // Check that the string argument is non-null. in evalstrLengthCommon()
1714 SVal ArgVal = state->getSVal(Arg.Expression, LCtx); in evalstrLengthCommon()
1737 SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); in evalstrLengthCommon()
1746 std::tie(stateStringTooLong, stateStringNotTooLong) = state->assume( in evalstrLengthCommon()
1770 state = state->assume(C.getSValBuilder().evalBinOpNN( in evalstrLengthCommon()
1776 state = state->assume(C.getSValBuilder().evalBinOpNN( in evalstrLengthCommon()
1796 state = state->BindExpr(Call.getOriginExpr(), LCtx, result); in evalstrLengthCommon()
1858 // It will append at most size - strlen(dst) - 1 bytes, in evalStrlcat()
1859 // NULL-terminating the result. in evalStrlcat()
1879 // Check that the destination is non-null. in evalStrcpyCommon()
1881 SVal DstVal = state->getSVal(Dst.Expression, LCtx); in evalStrcpyCommon()
1886 // Check that the source is non-null. in evalStrcpyCommon()
1888 SVal srcVal = state->getSVal(srcExpr.Expression, LCtx); in evalStrcpyCommon()
1910 // - actual overflows caused by a source that doesn't fit in the destination in evalStrcpyCommon()
1911 // - potential overflows caused by a bound that could exceed the destination in evalStrcpyCommon()
1932 SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); in evalStrcpyCommon()
1936 svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType()); in evalStrcpyCommon()
1948 // If the bound is equal to the source length, strncpy won't null- in evalStrcpyCommon()
1950 std::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume( in evalStrcpyCommon()
1972 // amountCopied = min (size - dstLen - 1 , srcLen) in evalStrcpyCommon()
1990 std::tie(TrueState, FalseState) = in evalStrcpyCommon()
1991 state->assume(hasEnoughSpace.castAs<DefinedOrUnknownSVal>()); in evalStrcpyCommon()
1993 // srcStrLength <= size - dstStrLength -1 in evalStrcpyCommon()
1998 // srcStrLength > size - dstStrLength -1 in evalStrcpyCommon()
2036 // case strncpy will do no work at all. Our bounds check uses n-1 in evalStrcpyCommon()
2039 std::tie(StateZeroSize, StateNonZeroSize) = in evalStrcpyCommon()
2046 StateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, DstVal); in evalStrcpyCommon()
2050 StateZeroSize = StateZeroSize->BindExpr(Call.getOriginExpr(), in evalStrcpyCommon()
2057 StateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, retSize); in evalStrcpyCommon()
2065 // We don't record the non-zero assumption here because we can't in evalStrcpyCommon()
2137 state = state->assume(sourceInResult.castAs<DefinedOrUnknownSVal>(), in evalStrcpyCommon()
2151 state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true); in evalStrcpyCommon()
2159 // Otherwise, this is a copy-over function (strcpy, strncpy, ...), and in evalStrcpyCommon()
2184 QualType ptrTy = Dst.Expression->getType(); in evalStrcpyCommon()
2219 // If this is a stpcpy-style copy, the last element is the return value. in evalStrcpyCommon()
2224 // Invalidate the destination (regular invalidation without pointer-escaping in evalStrcpyCommon()
2225 // the address of the top-level region). This must happen before we set the in evalStrcpyCommon()
2235 // Invalidate the source (const-invalidation without const-pointer-escaping in evalStrcpyCommon()
2236 // the address of the top-level region). in evalStrcpyCommon()
2241 // strncpy is annoying in that it doesn't guarantee to null-terminate in evalStrcpyCommon()
2243 // the bound (including the null-terminator), we don't know how long the in evalStrcpyCommon()
2248 state = setCStringLength(state, dstRegVal->getRegion(), finalStrLength); in evalStrcpyCommon()
2254 // If this is a stpcpy-style copy, but we were unable to check for a buffer in evalStrcpyCommon()
2262 state = state->BindExpr(Call.getOriginExpr(), LCtx, Result); in evalStrcpyCommon()
2296 // Check that the first string is non-null in evalStrcmpCommon()
2298 SVal LeftVal = state->getSVal(Left.Expression, LCtx); in evalStrcmpCommon()
2303 // Check that the second string is non-null. in evalStrcmpCommon()
2305 SVal RightVal = state->getSVal(Right.Expression, LCtx); in evalStrcmpCommon()
2330 std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf); in evalStrcmpCommon()
2336 StSameBuf->BindExpr(Call.getOriginExpr(), LCtx, in evalStrcmpCommon()
2361 StringRef LeftStrRef = LeftStrLiteral->getString(); in evalStrcmpCommon()
2362 StringRef RightStrRef = RightStrLiteral->getString(); in evalStrcmpCommon()
2367 SVal lenVal = state->getSVal(lenExpr, LCtx); in evalStrcmpCommon()
2372 LeftStrRef = LeftStrRef.substr(0, (size_t)len->getZExtValue()); in evalStrcmpCommon()
2373 RightStrRef = RightStrRef.substr(0, (size_t)len->getZExtValue()); in evalStrcmpCommon()
2409 state = state->assume(compareWithZeroVal, true); in evalStrcmpCommon()
2414 state = state->BindExpr(Call.getOriginExpr(), LCtx, resultVal); in evalStrcmpCommon()
2426 QualType CharPtrTy = SearchStrPtr.Expression->getType()->getPointeeType(); in evalStrsep()
2435 // Check that the search string pointer is non-null (though it may point to in evalStrsep()
2437 SVal SearchStrVal = State->getSVal(SearchStrPtr.Expression, LCtx); in evalStrsep()
2442 // Check that the delimiter string is non-null. in evalStrsep()
2444 SVal DelimStrVal = State->getSVal(DelimStr.Expression, LCtx); in evalStrsep()
2453 Result = State->getSVal(*SearchStrLoc, CharPtrTy); in evalStrsep()
2464 State->bindLoc(*SearchStrLoc, in evalStrsep()
2476 State = State->BindExpr(Call.getOriginExpr(), LCtx, Result); in evalStrsep()
2493 if (!Call.getArgExpr(2)->getType()->isPointerType()) in evalStdCopyCommon()
2507 SVal DstVal = State->getSVal(Dst, LCtx); in evalStdCopyCommon()
2517 State = State->BindExpr(Call.getOriginExpr(), LCtx, ResultVal); in evalStdCopyCommon()
2536 QualType SizeTy = Size.Expression->getType(); in evalMemset()
2539 std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy); in evalMemset()
2547 ZeroSize = ZeroSize->BindExpr(Call.getOriginExpr(), LCtx, BufferPtrVal); in evalMemset()
2569 State = State->BindExpr(Call.getOriginExpr(), LCtx, BufferPtrVal); in evalMemset()
2584 QualType SizeTy = Size.Expression->getType(); in evalBzero()
2587 std::tie(StateZeroSize, StateNonZeroSize) = in evalBzero()
2635 if (CE->getNumArgs() < NumParams) { in evalSprintfCommon()
2641 llvm::make_range(CE->getArgs(), CE->getArgs() + CE->getNumArgs()); in evalSprintfCommon()
2646 if (const QualType type = ArgExpr->getType(); in evalSprintfCommon()
2647 !type->isAnyPointerType() || in evalSprintfCommon()
2648 !type->getPointeeType()->isAnyCharacterType()) in evalSprintfCommon()
2666 //===----------------------------------------------------------------------===//
2668 //===----------------------------------------------------------------------===//
2685 // Pro-actively check that argument types are safe to do arithmetic upon. in identifyCall()
2689 for (auto I : CE->arguments()) { in identifyCall()
2690 QualType T = I->getType(); in identifyCall()
2691 if (!T->isIntegralOrEnumerationType() && !T->isPointerType()) in identifyCall()
2716 // properties are held. However, if the user chooses to turn off some of these in evalCall()
2726 for (const auto *I : DS->decls()) { in checkPreStmt()
2732 if (!D->getType()->isArrayType()) in checkPreStmt()
2735 const Expr *Init = D->getInit(); in checkPreStmt()
2741 Loc VarLoc = state->getLValue(D, C.getLocationContext()); in checkPreStmt()
2751 state = state->set<CStringLength>(MR, strLength); in checkPreStmt()
2764 CStringLengthTy Entries = state->get<CStringLength>(); in checkRegionChanges()
2771 // First build sets for the changed regions and their super-regions. in checkRegionChanges()
2777 MR = SR->getSuperRegion(); in checkRegionChanges()
2782 CStringLengthTy::Factory &F = state->get_context<CStringLength>(); in checkRegionChanges()
2786 // Is this entry for a super-region of a changed region? in checkRegionChanges()
2792 // Is this entry for a sub-region of a changed region? in checkRegionChanges()
2795 Super = SR->getSuperRegion(); in checkRegionChanges()
2803 return state->set<CStringLength>(Entries); in checkRegionChanges()
2809 CStringLengthTy Entries = state->get<CStringLength>(); in checkLiveSymbols()
2820 CStringLengthTy Entries = state->get<CStringLength>(); in checkDeadSymbols()
2824 CStringLengthTy::Factory &F = state->get_context<CStringLength>(); in checkDeadSymbols()
2832 state = state->set<CStringLength>(Entries); in checkDeadSymbols()
2847 checker->Filter.Check##name = true; \
2848 checker->Filter.CheckName##name = mgr.getCurrentCheckerName(); \