NoQ created this revision. If a state reset method is defined in a parent class, but called over an object of a child class, then the checker doesn't treat this as a state reset, at least for the sake of "Copying a 'moved-from' object" warning class.
The patch fixes it, but Peter may have a better fix in mind :) https://reviews.llvm.org/D31538 Files: lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp test/Analysis/MisusedMovedObject.cpp Index: test/Analysis/MisusedMovedObject.cpp =================================================================== --- test/Analysis/MisusedMovedObject.cpp +++ 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: lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ 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: test/Analysis/MisusedMovedObject.cpp =================================================================== --- test/Analysis/MisusedMovedObject.cpp +++ 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: lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits