Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -196,9 +196,8 @@ void evalBzero(CheckerContext &C, const CallExpr *CE) const; // Utility methods - std::pair - static assumeZero(CheckerContext &C, - ProgramStateRef state, SVal V, QualType Ty); + std::pair static assumeZero( + ProgramStateRef state, SVal V); static ProgramStateRef setCStringLength(ProgramStateRef state, const MemRegion *MR, @@ -279,16 +278,18 @@ // Individual checks and utility methods. //===----------------------------------------------------------------------===// -std::pair -CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, - QualType Ty) { - Optional val = V.getAs(); - if (!val) - return std::pair(state, state); +std::pair +CStringChecker::assumeZero(ProgramStateRef state, SVal V) { + auto states = std::make_pair(state, state); - SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); - return state->assume(svalBuilder.evalEQ(state, *val, zero)); + // FIXME: Not all SVal kinds are handled by ProgramState::assume(). + // See SimpleConstraintManager::assumeAux(). + if (!V.getAs() && !V.getAs()) + if (auto val = V.getAs()) + // Returned pair shall be {null, non-null} so reorder states. + std::tie(states.second, states.first) = state->assume(*val); + + return states; } ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, @@ -299,8 +300,7 @@ return nullptr; ProgramStateRef stateNull, stateNonNull; - std::tie(stateNull, stateNonNull) = - assumeZero(C, State, l, Arg.Expression->getType()); + std::tie(stateNull, stateNonNull) = assumeZero(State, l); if (stateNull && !stateNonNull) { if (Filter.CheckCStringNullArg) { @@ -1071,8 +1071,7 @@ CharVal = svalBuilder.evalCast(CharVal, Ctx.UnsignedCharTy, Ctx.IntTy); ProgramStateRef StateNullChar, StateNonNullChar; - std::tie(StateNullChar, StateNonNullChar) = - assumeZero(C, State, CharVal, Ctx.UnsignedCharTy); + std::tie(StateNullChar, StateNonNullChar) = assumeZero(State, CharVal); if (StateWholeReg && !StateNotWholeReg && StateNullChar && !StateNonNullChar) { @@ -1133,11 +1132,9 @@ // See if the size argument is zero. const LocationContext *LCtx = C.getLocationContext(); SVal sizeVal = state->getSVal(Size.Expression, LCtx); - QualType sizeTy = Size.Expression->getType(); ProgramStateRef stateZeroSize, stateNonZeroSize; - std::tie(stateZeroSize, stateNonZeroSize) = - assumeZero(C, state, sizeVal, sizeTy); + std::tie(stateZeroSize, stateNonZeroSize) = assumeZero(state, sizeVal); // Get the value of the Dest. SVal destVal = state->getSVal(Dest.Expression, LCtx); @@ -1287,11 +1284,9 @@ // See if the size argument is zero. SVal sizeVal = State->getSVal(Size.Expression, LCtx); - QualType sizeTy = Size.Expression->getType(); ProgramStateRef stateZeroSize, stateNonZeroSize; - std::tie(stateZeroSize, stateNonZeroSize) = - assumeZero(C, State, sizeVal, sizeTy); + std::tie(stateZeroSize, stateNonZeroSize) = assumeZero(State, sizeVal); // If the size can be zero, the result will be 0 in that case, and we don't // have to check either of the buffers. @@ -1367,8 +1362,7 @@ SVal maxlenVal = state->getSVal(maxlenExpr, LCtx); ProgramStateRef stateZeroSize, stateNonZeroSize; - std::tie(stateZeroSize, stateNonZeroSize) = - assumeZero(C, state, maxlenVal, maxlenExpr->getType()); + std::tie(stateZeroSize, stateNonZeroSize) = assumeZero(state, maxlenVal); // If the size can be zero, the result will be 0 in that case, and we don't // have to check the string itself. @@ -1706,7 +1700,7 @@ // as the last element accessed, so n == 0 is problematic. ProgramStateRef StateZeroSize, StateNonZeroSize; std::tie(StateZeroSize, StateNonZeroSize) = - assumeZero(C, state, *lenValNL, sizeTy); + assumeZero(state, *lenValNL); // If the size is known to be zero, we're done. if (StateZeroSize && !StateNonZeroSize) { @@ -2177,10 +2171,9 @@ // See if the size argument is zero. const LocationContext *LCtx = C.getLocationContext(); SVal SizeVal = C.getSVal(Size.Expression); - QualType SizeTy = Size.Expression->getType(); ProgramStateRef ZeroSize, NonZeroSize; - std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy); + std::tie(ZeroSize, NonZeroSize) = assumeZero(State, SizeVal); // Get the value of the memory area. SVal BufferPtrVal = C.getSVal(Buffer.Expression); @@ -2225,11 +2218,9 @@ // See if the size argument is zero. SVal SizeVal = C.getSVal(Size.Expression); - QualType SizeTy = Size.Expression->getType(); ProgramStateRef StateZeroSize, StateNonZeroSize; - std::tie(StateZeroSize, StateNonZeroSize) = - assumeZero(C, State, SizeVal, SizeTy); + std::tie(StateZeroSize, StateNonZeroSize) = assumeZero(State, SizeVal); // If the size is zero, there won't be any actual memory access, // In this case we just return.