improve refcounting loplugin to check SvRef-based classes
Change-Id: I2b3c8eedabeaecd8dcae9fe69c951353a5686883 Reviewed-on: https://gerrit.libreoffice.org/17521 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
This commit is contained in:
committed by
Noel Grandin
parent
a5b842f3aa
commit
9c1f700aff
@@ -215,7 +215,81 @@ bool containsXInterfaceSubclass(const Type* pType0) {
|
||||
}
|
||||
}
|
||||
|
||||
bool containsSvRefBaseSubclass(const Type* pType0) {
|
||||
if (!pType0)
|
||||
return false;
|
||||
const Type* pType = pType0->getUnqualifiedDesugaredType();
|
||||
if (!pType)
|
||||
return false;
|
||||
const CXXRecordDecl* pRecordDecl = pType->getAsCXXRecordDecl();
|
||||
if (pRecordDecl) {
|
||||
pRecordDecl = pRecordDecl->getCanonicalDecl();
|
||||
}
|
||||
if (pRecordDecl) {
|
||||
const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
|
||||
if (pTemplate) {
|
||||
std::string aName = pTemplate->getQualifiedNameAsString();
|
||||
if (aName == "tools::SvRef")
|
||||
return false;
|
||||
for(unsigned i=0; i<pTemplate->getTemplateArgs().size(); ++i) {
|
||||
const TemplateArgument& rArg = pTemplate->getTemplateArgs()[i];
|
||||
if (rArg.getKind() == TemplateArgument::ArgKind::Type &&
|
||||
containsSvRefBaseSubclass(rArg.getAsType().getTypePtr()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pType->isPointerType()) {
|
||||
// ignore
|
||||
return false;
|
||||
} else if (pType->isArrayType()) {
|
||||
const ArrayType* pArrayType = dyn_cast<ArrayType>(pType);
|
||||
QualType elementType = pArrayType->getElementType();
|
||||
return containsSvRefBaseSubclass(elementType.getTypePtr());
|
||||
} else {
|
||||
return isDerivedFrom(pRecordDecl, "tools::SvRefBase");
|
||||
}
|
||||
}
|
||||
|
||||
bool containsSalhelperReferenceObjectSubclass(const Type* pType0) {
|
||||
if (!pType0)
|
||||
return false;
|
||||
const Type* pType = pType0->getUnqualifiedDesugaredType();
|
||||
if (!pType)
|
||||
return false;
|
||||
const CXXRecordDecl* pRecordDecl = pType->getAsCXXRecordDecl();
|
||||
if (pRecordDecl) {
|
||||
pRecordDecl = pRecordDecl->getCanonicalDecl();
|
||||
}
|
||||
if (pRecordDecl) {
|
||||
const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
|
||||
if (pTemplate) {
|
||||
std::string aName = pTemplate->getQualifiedNameAsString();
|
||||
if (aName == "rtl::Reference" || aName == "store::OStoreHandle")
|
||||
return false;
|
||||
for(unsigned i=0; i<pTemplate->getTemplateArgs().size(); ++i) {
|
||||
const TemplateArgument& rArg = pTemplate->getTemplateArgs()[i];
|
||||
if (rArg.getKind() == TemplateArgument::ArgKind::Type &&
|
||||
containsSalhelperReferenceObjectSubclass(rArg.getAsType().getTypePtr()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pType->isPointerType()) {
|
||||
// ignore
|
||||
return false;
|
||||
} else if (pType->isArrayType()) {
|
||||
const ArrayType* pArrayType = dyn_cast<ArrayType>(pType);
|
||||
QualType elementType = pArrayType->getElementType();
|
||||
return containsSalhelperReferenceObjectSubclass(elementType.getTypePtr());
|
||||
} else {
|
||||
return isDerivedFrom(pRecordDecl, "salhelper::SimpleReferenceObject");
|
||||
}
|
||||
}
|
||||
|
||||
bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) {
|
||||
if (ignoreLocation(fieldDecl)) {
|
||||
@@ -224,7 +298,29 @@ bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) {
|
||||
if (fieldDecl->isBitField()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string aParentName = fieldDecl->getParent()->getQualifiedNameAsString();
|
||||
|
||||
if (containsSvRefBaseSubclass(fieldDecl->getType().getTypePtr())) {
|
||||
report(
|
||||
DiagnosticsEngine::Warning,
|
||||
"SvRefBase subclass being directly heap managed, should be managed via tools::SvRef, "
|
||||
+ fieldDecl->getType().getAsString()
|
||||
+ ", parent is " + aParentName,
|
||||
fieldDecl->getLocation())
|
||||
<< fieldDecl->getSourceRange();
|
||||
}
|
||||
|
||||
if (containsSalhelperReferenceObjectSubclass(fieldDecl->getType().getTypePtr())) {
|
||||
report(
|
||||
DiagnosticsEngine::Warning,
|
||||
"salhelper::SimpleReferenceObject subclass being directly heap managed, should be managed via rtl::Reference, "
|
||||
+ fieldDecl->getType().getAsString()
|
||||
+ ", parent is " + aParentName,
|
||||
fieldDecl->getLocation())
|
||||
<< fieldDecl->getSourceRange();
|
||||
}
|
||||
|
||||
if ( aParentName == "com::sun::star::uno::BaseReference"
|
||||
|| aParentName == "cppu::detail::element_alias"
|
||||
// this is playing some kind of game to avoid circular references
|
||||
@@ -241,7 +337,6 @@ bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) {
|
||||
+ ", parent is " + aParentName,
|
||||
fieldDecl->getLocation())
|
||||
<< fieldDecl->getSourceRange();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -251,6 +346,29 @@ bool RefCounting::VisitVarDecl(const VarDecl * varDecl) {
|
||||
if (ignoreLocation(varDecl)) {
|
||||
return true;
|
||||
}
|
||||
if (isa<ParmVarDecl>(varDecl)) {
|
||||
return true;
|
||||
}
|
||||
if (containsSvRefBaseSubclass(varDecl->getType().getTypePtr())) {
|
||||
report(
|
||||
DiagnosticsEngine::Warning,
|
||||
"SvRefBase subclass being directly stack managed, should be managed via tools::SvRef, "
|
||||
+ varDecl->getType().getAsString(),
|
||||
varDecl->getLocation())
|
||||
<< varDecl->getSourceRange();
|
||||
}
|
||||
if (containsSalhelperReferenceObjectSubclass(varDecl->getType().getTypePtr())) {
|
||||
StringRef name { compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())) };
|
||||
// this is playing games that it believes is safe
|
||||
if (name == SRCDIR "/stoc/source/security/permissions.cxx")
|
||||
return true;
|
||||
report(
|
||||
DiagnosticsEngine::Warning,
|
||||
"salhelper::SimpleReferenceObject subclass being directly stack managed, should be managed via rtl::Reference, "
|
||||
+ varDecl->getType().getAsString(),
|
||||
varDecl->getLocation())
|
||||
<< varDecl->getSourceRange();
|
||||
}
|
||||
if (containsXInterfaceSubclass(varDecl->getType())) {
|
||||
report(
|
||||
DiagnosticsEngine::Warning,
|
||||
|
Reference in New Issue
Block a user