From 18e9d0430b722cf77afe96262f6d16f3c9c8a8b6 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Tue, 10 Oct 2017 11:55:56 +0000 Subject: [PATCH] [analyzer] MisusedMovedObject: Fix state-resetting a base-class sub-object. If a method is resetting the state of an object that was moved from, it should be safe to use this object again. However if the method was defined in a parent class, but used in a child class, the reset didn't happen from the checker's perspective. Differential Revision: https://reviews.llvm.org/D31538 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315301 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/MisusedMovedObjectChecker.cpp | 9 ++++++++- test/Analysis/MisusedMovedObject.cpp | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp index 70da66dba4..4b69a1bd1e 100644 --- a/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -416,7 +416,14 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, return; if (isStateResetMethod(MethodDecl)) { - State = State->remove(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(WholeObjectRegion)) + WholeObjectRegion = BR->getSuperRegion(); + + State = State->remove(WholeObjectRegion); C.addTransition(State); return; } diff --git a/test/Analysis/MisusedMovedObject.cpp b/test/Analysis/MisusedMovedObject.cpp index 44e055fd40..57c1ecc912 100644 --- a/test/Analysis/MisusedMovedObject.cpp +++ b/test/Analysis/MisusedMovedObject.cpp @@ -617,3 +617,11 @@ void subRegionMoveTest() { 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 +} -- 2.40.0