forked from OSchip/llvm-project
[analyzer] Support Reinitializes attribute in MisusedMovedObject check
Differential Revision: https://reviews.llvm.org/D52983 llvm-svn: 344017
This commit is contained in:
parent
7ce9334ad7
commit
d1fd93ceea
|
@ -314,17 +314,18 @@ bool MisusedMovedObjectChecker::isMoveSafeMethod(
|
|||
return true;
|
||||
}
|
||||
// Function call `empty` can be skipped.
|
||||
if (MethodDec && MethodDec->getDeclName().isIdentifier() &&
|
||||
return (MethodDec && MethodDec->getDeclName().isIdentifier() &&
|
||||
(MethodDec->getName().lower() == "empty" ||
|
||||
MethodDec->getName().lower() == "isempty"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
MethodDec->getName().lower() == "isempty"));
|
||||
}
|
||||
|
||||
bool MisusedMovedObjectChecker::isStateResetMethod(
|
||||
const CXXMethodDecl *MethodDec) const {
|
||||
if (MethodDec && MethodDec->getDeclName().isIdentifier()) {
|
||||
if (!MethodDec)
|
||||
return false;
|
||||
if (MethodDec->hasAttr<ReinitializesAttr>())
|
||||
return true;
|
||||
if (MethodDec->getDeclName().isIdentifier()) {
|
||||
std::string MethodName = MethodDec->getName().lower();
|
||||
if (MethodName == "reset" || MethodName == "clear" ||
|
||||
MethodName == "destroy")
|
||||
|
@ -429,8 +430,7 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call,
|
|||
|
||||
// We want to investigate the whole object, not only sub-object of a parent
|
||||
// class in which the encountered method defined.
|
||||
while (const CXXBaseObjectRegion *BR =
|
||||
dyn_cast<CXXBaseObjectRegion>(ThisRegion))
|
||||
while (const auto *BR = dyn_cast<CXXBaseObjectRegion>(ThisRegion))
|
||||
ThisRegion = BR->getSuperRegion();
|
||||
|
||||
if (isMoveSafeMethod(MethodDecl))
|
||||
|
@ -487,13 +487,9 @@ ProgramStateRef MisusedMovedObjectChecker::checkRegionChanges(
|
|||
ThisRegion = IC->getCXXThisVal().getAsRegion();
|
||||
}
|
||||
|
||||
for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
|
||||
E = ExplicitRegions.end();
|
||||
I != E; ++I) {
|
||||
const auto *Region = *I;
|
||||
if (ThisRegion != Region) {
|
||||
for (const auto *Region : ExplicitRegions) {
|
||||
if (ThisRegion != Region)
|
||||
State = removeFromState(State, Region);
|
||||
}
|
||||
}
|
||||
|
||||
return State;
|
||||
|
|
|
@ -638,7 +638,10 @@ void ifStmtSequencesDeclAndConditionTest() {
|
|||
}
|
||||
}
|
||||
|
||||
class C : public A {};
|
||||
struct C : public A {
|
||||
[[clang::reinitializes]] void reinit();
|
||||
};
|
||||
|
||||
void subRegionMoveTest() {
|
||||
{
|
||||
A a;
|
||||
|
@ -672,6 +675,13 @@ void resetSuperClass() {
|
|||
C c2 = c; // no-warning
|
||||
}
|
||||
|
||||
void resetSuperClass2() {
|
||||
C c;
|
||||
C c1 = std::move(c);
|
||||
c.reinit();
|
||||
C c2 = c; // no-warning
|
||||
}
|
||||
|
||||
void reportSuperClass() {
|
||||
C c;
|
||||
C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}}
|
||||
|
|
Loading…
Reference in New Issue