Index: lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -43,10 +43,9 @@ }; class MisusedMovedObjectChecker - : public Checker { public: - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; void checkPreCall(const CallEvent &MC, CheckerContext &C) const; void checkPostCall(const CallEvent &MC, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; @@ -218,42 +217,6 @@ return nullptr; } -// Removing the function parameters' MemRegion from the state. This is needed -// for PODs where the trivial destructor does not even created nor executed. -void MisusedMovedObjectChecker::checkEndFunction(const ReturnStmt *RS, - CheckerContext &C) const { - auto State = C.getState(); - TrackedRegionMapTy Objects = State->get(); - if (Objects.isEmpty()) - return; - - auto LC = C.getLocationContext(); - - const auto LD = dyn_cast_or_null(LC->getDecl()); - if (!LD) - return; - llvm::SmallSet InvalidRegions; - - for (auto Param : LD->parameters()) { - auto Type = Param->getType().getTypePtrOrNull(); - if (!Type) - continue; - if (!Type->isPointerType() && !Type->isReferenceType()) { - InvalidRegions.insert(State->getLValue(Param, LC).getAsRegion()); - } - } - - if (InvalidRegions.empty()) - return; - - for (const auto &E : State->get()) { - if (InvalidRegions.count(E.first->getBaseRegion())) - State = State->remove(E.first); - } - - C.addTransition(State); -} - void MisusedMovedObjectChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { const auto *AFC = dyn_cast(&Call); @@ -384,6 +347,10 @@ return; } + // Calling a destructor on a moved object is fine. + if (isa(&Call)) + return; + const auto IC = dyn_cast(&Call); if (!IC) return; @@ -392,12 +359,6 @@ if (!ThisRegion) return; - if (dyn_cast_or_null(Call.getDecl())) { - State = removeFromState(State, ThisRegion); - C.addTransition(State); - return; - } - const auto MethodDecl = dyn_cast_or_null(IC->getDecl()); if (!MethodDecl) return; Index: test/Analysis/MisusedMovedObject.cpp =================================================================== --- test/Analysis/MisusedMovedObject.cpp +++ test/Analysis/MisusedMovedObject.cpp @@ -710,3 +710,15 @@ Empty f = std::move(e); // no-warning } } + +struct MoveOnlyWithDestructor { + MoveOnlyWithDestructor(); + ~MoveOnlyWithDestructor(); + MoveOnlyWithDestructor(const MoveOnlyWithDestructor &m) = delete; + MoveOnlyWithDestructor(MoveOnlyWithDestructor &&m); +}; + +MoveOnlyWithDestructor foo() { + MoveOnlyWithDestructor m; + return m; +}