This revision was automatically updated to reflect the committed changes. Closed by commit rL315301: [analyzer] MisusedMovedObject: Fix state-resetting a base-class sub-object. (authored by dergachev).
Changed prior to commit: https://reviews.llvm.org/D31538?vs=93652&id=118351#toc Repository: rL LLVM https://reviews.llvm.org/D31538 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp cfe/trunk/test/Analysis/MisusedMovedObject.cpp Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -416,7 +416,14 @@ return; if (isStateResetMethod(MethodDecl)) { - State = State->remove<TrackedRegionMap>(ThisRegion); + // A state reset method resets the whole object, not only sub-object + // of a parent class in which it is defined. + const MemRegion *WholeObjectRegion = ThisRegion; + while (const CXXBaseObjectRegion *BR = + dyn_cast<CXXBaseObjectRegion>(WholeObjectRegion)) + WholeObjectRegion = BR->getSuperRegion(); + + State = State->remove<TrackedRegionMap>(WholeObjectRegion); C.addTransition(State); return; } Index: cfe/trunk/test/Analysis/MisusedMovedObject.cpp =================================================================== --- cfe/trunk/test/Analysis/MisusedMovedObject.cpp +++ cfe/trunk/test/Analysis/MisusedMovedObject.cpp @@ -617,3 +617,11 @@ a.b.foo(); // no-warning } } + +class C: public A {}; +void resetSuperClass() { + C c; + C c1 = std::move(c); + c.clear(); + C c2 = c; // no-warning +}
Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -416,7 +416,14 @@ return; if (isStateResetMethod(MethodDecl)) { - State = State->remove<TrackedRegionMap>(ThisRegion); + // A state reset method resets the whole object, not only sub-object + // of a parent class in which it is defined. + const MemRegion *WholeObjectRegion = ThisRegion; + while (const CXXBaseObjectRegion *BR = + dyn_cast<CXXBaseObjectRegion>(WholeObjectRegion)) + WholeObjectRegion = BR->getSuperRegion(); + + State = State->remove<TrackedRegionMap>(WholeObjectRegion); C.addTransition(State); return; } Index: cfe/trunk/test/Analysis/MisusedMovedObject.cpp =================================================================== --- cfe/trunk/test/Analysis/MisusedMovedObject.cpp +++ cfe/trunk/test/Analysis/MisusedMovedObject.cpp @@ -617,3 +617,11 @@ a.b.foo(); // no-warning } } + +class C: public A {}; +void resetSuperClass() { + C c; + C c1 = std::move(c); + c.clear(); + C c2 = c; // no-warning +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits