vabridgers updated this revision to Diff 409750. vabridgers added a comment.
Address NoQ comments Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D119601/new/ https://reviews.llvm.org/D119601 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp clang/lib/StaticAnalyzer/Core/RegionStore.cpp clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -61,7 +61,7 @@ DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) { if (Loc::isLocType(type)) - return makeNull(); + return makeNullWithType(type); if (type->isIntegralOrEnumerationType()) return makeIntVal(0, type); @@ -359,7 +359,7 @@ return makeBoolVal(cast<ObjCBoolLiteralExpr>(E)); case Stmt::CXXNullPtrLiteralExprClass: - return makeNull(); + return makeNullWithType(E->getType()); case Stmt::CStyleCastExprClass: case Stmt::CXXFunctionalCastExprClass: @@ -399,7 +399,7 @@ if (Loc::isLocType(E->getType())) if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) - return makeNull(); + return makeNullWithType(E->getType()); return None; } Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2410,7 +2410,7 @@ SVal V; if (Loc::isLocType(T)) - V = svalBuilder.makeNull(); + V = svalBuilder.makeNullWithType(T); else if (T->isIntegralOrEnumerationType()) V = svalBuilder.makeZeroVal(T); else if (T->isStructureOrClassType() || T->isArrayType()) { Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -460,7 +460,8 @@ continue; } else { // If the cast fails on a pointer, bind to 0. - state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull()); + state = state->BindExpr(CastE, LCtx, + svalBuilder.makeNullWithType(resultType)); } } else { // If we don't know if the cast succeeded, conjure a new symbol. @@ -498,7 +499,7 @@ continue; } case CK_NullToPointer: { - SVal V = svalBuilder.makeNull(); + SVal V = svalBuilder.makeNullWithType(CastE->getType()); state = state->BindExpr(CastE, LCtx, V); Bldr.generateNode(CastE, Pred, state); continue; Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -549,8 +549,9 @@ State->BindExpr(CE, C.getLocationContext(), *StreamVal); // Generate state for NULL return value. // Stream switches to OpenFailed state. - ProgramStateRef StateRetNull = State->BindExpr(CE, C.getLocationContext(), - C.getSValBuilder().makeNull()); + ProgramStateRef StateRetNull = + State->BindExpr(CE, C.getLocationContext(), + C.getSValBuilder().makeNullWithType(CE->getType())); StateRetNotNull = StateRetNotNull->set<StreamMap>(StreamSym, StreamState::getOpened(Desc)); Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -71,7 +71,8 @@ bool handleMoveCtr(const CallEvent &Call, CheckerContext &C, const MemRegion *ThisRegion) const; bool updateMovedSmartPointers(CheckerContext &C, const MemRegion *ThisRegion, - const MemRegion *OtherSmartPtrRegion) const; + const MemRegion *OtherSmartPtrRegion, + const CallEvent &Call) const; void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const; bool handleComparisionOp(const CallEvent &Call, CheckerContext &C) const; bool handleOstreamOperator(const CallEvent &Call, CheckerContext &C) const; @@ -119,6 +120,20 @@ return isStdSmartPtr(E->getType()->getAsCXXRecordDecl()); } +static QualType getTemplateSpecializationArgType(CheckerContext &C, + const CallEvent &Call, + unsigned ndx) { + const ClassTemplateSpecializationDecl *SpecDecl = + cast<ClassTemplateSpecializationDecl>( + cast<CXXMethodDecl>(Call.getDecl())->getParent()); + ArrayRef<TemplateArgument> TemplateArgs = + SpecDecl->getTemplateArgs().asArray(); + const TemplateArgument &T = TemplateArgs[ndx]; + assert(T.getKind() == TemplateArgument::Type); + QualType Ty = C.getASTContext().getPointerType(T.getAsType()); + return Ty; +} + // Define the inter-checker API. namespace clang { namespace ento { @@ -383,7 +398,8 @@ return handleMoveCtr(Call, C, ThisRegion); if (Call.getNumArgs() == 0) { - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType( + CC->getCXXThisVal().getType(C.getASTContext())); State = State->set<TrackedRegionMap>(ThisRegion, NullVal); C.addTransition( @@ -640,7 +656,8 @@ *InnerPointVal); } - auto ValueToUpdate = C.getSValBuilder().makeNull(); + auto ValueToUpdate = + C.getSValBuilder().makeNullWithType(Call.getResultType()); State = State->set<TrackedRegionMap>(ThisRegion, ValueToUpdate); C.addTransition(State, C.getNoteTag([ThisRegion](PathSensitiveBugReport &BR, @@ -744,7 +761,7 @@ bool AssignedNull = Call.getArgSVal(0).isZeroConstant(); if (!AssignedNull) return false; - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType(Call.getResultType()); State = State->set<TrackedRegionMap>(ThisRegion, NullVal); C.addTransition(State, C.getNoteTag([ThisRegion](PathSensitiveBugReport &BR, llvm::raw_ostream &OS) { @@ -758,7 +775,7 @@ return true; } - return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion); + return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion, Call); } bool SmartPtrModeling::handleMoveCtr(const CallEvent &Call, CheckerContext &C, @@ -767,17 +784,19 @@ if (!OtherSmartPtrRegion) return false; - return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion); + return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion, Call); } bool SmartPtrModeling::updateMovedSmartPointers( CheckerContext &C, const MemRegion *ThisRegion, - const MemRegion *OtherSmartPtrRegion) const { + const MemRegion *OtherSmartPtrRegion, const CallEvent &Call) const { ProgramStateRef State = C.getState(); const auto *OtherInnerPtr = State->get<TrackedRegionMap>(OtherSmartPtrRegion); if (OtherInnerPtr) { State = State->set<TrackedRegionMap>(ThisRegion, *OtherInnerPtr); - auto NullVal = C.getSValBuilder().makeNull(); + + auto NullVal = C.getSValBuilder().makeNullWithType( + getTemplateSpecializationArgType(C, Call, 0)); State = State->set<TrackedRegionMap>(OtherSmartPtrRegion, NullVal); bool IsArgValNull = OtherInnerPtr->isZeroConstant(); @@ -803,7 +822,9 @@ } else { // In case we dont know anything about value we are moving from // remove the entry from map for which smart pointer got moved to. - auto NullVal = C.getSValBuilder().makeNull(); + // For unique_ptr<A>, Ty will be 'A*'. + auto NullVal = C.getSValBuilder().makeNullWithType( + getTemplateSpecializationArgType(C, Call, 0)); State = State->remove<TrackedRegionMap>(ThisRegion); State = State->set<TrackedRegionMap>(OtherSmartPtrRegion, NullVal); C.addTransition(State, C.getNoteTag([OtherSmartPtrRegion, @@ -868,7 +889,8 @@ std::tie(NotNullState, NullState) = State->assume(InnerPointerVal.castAs<DefinedOrUnknownSVal>()); - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType( + C.getASTContext().getPointerType(Call.getResultType())); // Explicitly tracking the region as null. NullState = NullState->set<TrackedRegionMap>(ThisRegion, NullVal); Index: clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -945,7 +945,8 @@ // Assume that output is zero on the other branch. NullOutputState = NullOutputState->BindExpr( - CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false); + CE, LCtx, C.getSValBuilder().makeNullWithType(ResultTy), + /*Invalidate=*/false); C.addTransition(NullOutputState, &getCastFailTag()); // And on the original branch assume that both input and Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -2551,8 +2551,8 @@ SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal PtrEQ = - svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull()); + DefinedOrUnknownSVal PtrEQ = svalBuilder.evalEQ( + State, arg0Val, svalBuilder.makeNullWithType(arg0Expr->getType())); // Get the size argument. const Expr *Arg1 = CE->getArg(1); Index: clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp @@ -250,7 +250,7 @@ CastSucceeds); SVal V = CastSucceeds ? C.getSValBuilder().evalCast(DV, CastToTy, CastFromTy) - : C.getSValBuilder().makeNull(); + : C.getSValBuilder().makeNullWithType(CastToTy); C.addTransition( State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), V, false), getNoteTag(C, CastInfo, CastToTy, Object, CastSucceeds, IsKnownCast)); @@ -359,7 +359,9 @@ if (ProgramStateRef State = C.getState()->assume(DV, false)) C.addTransition(State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), - C.getSValBuilder().makeNull(), false), + C.getSValBuilder().makeNullWithType( + Call.getOriginExpr()->getType()), + false), C.getNoteTag("Assuming null pointer is passed into cast", /*IsPrunable=*/true)); } Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -365,11 +365,15 @@ /// space. /// \param type pointer type. Loc makeNullWithType(QualType type) { - return loc::ConcreteInt(BasicVals.getZeroWithTypeSize(type)); - } - - Loc makeNull() { - return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); + assert((type->isPointerType() || type->isObjCObjectPointerType() || + type->isBlockPointerType() || type->isNullPtrType() || + type->isReferenceType()) && + "makeNullWithType must use pointer type"); + QualType nullType = type; + if (type->isReferenceType()) { + nullType = Context.getPointerType(type->getPointeeType()); + } + return loc::ConcreteInt(BasicVals.getZeroWithTypeSize(nullType)); } Loc makeLoc(SymbolRef sym) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits