private: bool isSolarMutexLockGuardStmt(const Stmt*); const CXXThisExpr* isOtherMutexLockGuardStmt(const Stmt*);
std::vector<bool> m_TouchesThis; // so we ignore the CxxThisEpxr that references the maMutex in the guard expression
std::vector<const CXXThisExpr*> m_IgnoreThis;
};
bool UnnecessaryLocking::VisitCompoundStmt(const CompoundStmt* compoundStmt)
{ if (ignoreLocation(compoundStmt)) returntrue; if (compoundStmt->size() < 1) returntrue;
bool UnnecessaryLocking::isSolarMutexLockGuardStmt(const Stmt* stmt)
{ auto declStmt = dyn_cast<DeclStmt>(stmt); if (!declStmt) returnfalse; if (!declStmt->isSingleDecl()) returnfalse; auto varDecl = dyn_cast<VarDecl>(declStmt->getSingleDecl()); if (!varDecl) returnfalse; auto tc = loplugin::TypeCheck(varDecl->getType()); if (!tc.Class("SolarMutexGuard").GlobalNamespace()
&& !tc.Class("SolarMutexClearableGuard").GlobalNamespace()
&& !tc.Class("SolarMutexResettableGuard").GlobalNamespace()
&& !tc.Class("SolarMutexTryAndBuyGuard").GlobalNamespace()) returnfalse; returntrue;
}
const CXXThisExpr* UnnecessaryLocking::isOtherMutexLockGuardStmt(const Stmt* stmt)
{ auto declStmt = dyn_cast<DeclStmt>(stmt); if (!declStmt) return nullptr; if (!declStmt->isSingleDecl()) return nullptr; auto varDecl = dyn_cast<VarDecl>(declStmt->getSingleDecl()); if (!varDecl) return nullptr; auto tc = loplugin::TypeCheck(varDecl->getType()); if (!tc.Class("unique_lock").StdNamespace() && !tc.Class("scoped_lock").StdNamespace()
&& !tc.Class("Guard") && !tc.Class("ClearableGuard") && !tc.Class("ResettableGuard")) return nullptr; auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(varDecl->getInit()); if (!cxxConstructExpr || cxxConstructExpr->getNumArgs() < 1) return nullptr; auto arg0 = cxxConstructExpr->getArg(0); if (auto memberExpr = dyn_cast<MemberExpr>(arg0))
{ const CXXThisExpr* thisStmt
= dyn_cast<CXXThisExpr>(memberExpr->getBase()->IgnoreImplicit()); return thisStmt;
} elseif (auto memberCallExpr = dyn_cast<CXXMemberCallExpr>(arg0))
{ return dyn_cast_or_null<CXXThisExpr>(
memberCallExpr->getImplicitObjectArgument()->IgnoreImplicit());
} return nullptr;
}
bool UnnecessaryLocking::VisitCXXThisExpr(const CXXThisExpr* cxxThisExpr)
{ if (ignoreLocation(cxxThisExpr)) returntrue; // just in case if (m_TouchesThis.empty()) returntrue; // already found something if (m_TouchesThis.back()) returntrue; if (m_IgnoreThis.back() && m_IgnoreThis.back() == cxxThisExpr) returntrue;
m_TouchesThis.back() = true; returntrue;
}
bool UnnecessaryLocking::VisitCallExpr(const CallExpr* callExpr)
{ if (ignoreLocation(callExpr)) returntrue; // just in case if (m_TouchesThis.empty()) returntrue; // already found something if (m_TouchesThis.back()) returntrue; const CXXMethodDecl* callee = dyn_cast_or_null<CXXMethodDecl>(callExpr->getDirectCallee()); if (!callee) returntrue; auto dc = loplugin::DeclCheck(callee->getParent()); if (dc.Class("VCLUnoHelper") || dc.Class("Application"))
m_TouchesThis.back() = true; returntrue;
}
/** off by default because each warning needs to be carefully inspected */
loplugin::Plugin::Registration<UnnecessaryLocking> unnecessarylocking("unnecessarylocking", false);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.