Kaydet (Commit) 6397b93e authored tarafından Stephan Bergmann's avatar Stephan Bergmann

loplugin:salbool: Fix handling of potentially overriding functions

Change-Id: I63d00cf5ab1dac953fae07ca4eb4d987610551a2
üst be8d4a5d
...@@ -52,15 +52,20 @@ bool hasCLanguageLinkageType(FunctionDecl const * decl) { ...@@ -52,15 +52,20 @@ bool hasCLanguageLinkageType(FunctionDecl const * decl) {
return false; return false;
} }
bool canOverrideTemplateArgumentMember(CXXMethodDecl const * decl) { enum class OverrideKind { NO, YES, MAYBE };
CXXRecordDecl const * r = dyn_cast<CXXRecordDecl>(decl->getDeclContext());
assert(r != nullptr); OverrideKind getOverrideKind(FunctionDecl const * decl) {
for (auto b = r->bases_begin(); b != r->bases_end(); ++b) { CXXMethodDecl const * m = dyn_cast<CXXMethodDecl>(decl);
if (b->getType()->isTemplateTypeParmType()) { if (m == nullptr) {
return true; return OverrideKind::NO;
}
} }
return false; if (m->size_overridden_methods() != 0 || m->hasAttr<OverrideAttr>()) {
return OverrideKind::YES;
}
if (!dyn_cast<CXXRecordDecl>(m->getDeclContext())->hasAnyDependentBases()) {
return OverrideKind::NO;
}
return OverrideKind::MAYBE;
} }
//TODO: current implementation is not at all general, just tests what we //TODO: current implementation is not at all general, just tests what we
...@@ -284,11 +289,8 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) { ...@@ -284,11 +289,8 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) {
|| hasBoolOverload(f))) || hasBoolOverload(f)))
|| f->isDeleted())) || f->isDeleted()))
{ {
CXXMethodDecl const * m = dyn_cast<CXXMethodDecl>(f); OverrideKind k = getOverrideKind(f);
//XXX: canOverrideTemplateArgumentMember(m) does not require if (k != OverrideKind::YES) {
// !m->isVirtual()
if ((m == nullptr || !m->isVirtual()))
{
SourceLocation loc { decl->getLocStart() }; SourceLocation loc { decl->getLocStart() };
TypeSourceInfo * tsi = decl->getTypeSourceInfo(); TypeSourceInfo * tsi = decl->getTypeSourceInfo();
if (tsi != nullptr) { if (tsi != nullptr) {
...@@ -326,7 +328,14 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) { ...@@ -326,7 +328,14 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) {
// definition (in a main file only processed later) to fail // definition (in a main file only processed later) to fail
// with a "mismatch" error before the rewriter had a chance // with a "mismatch" error before the rewriter had a chance
// to act upon the definition (but use the heuristic of // to act upon the definition (but use the heuristic of
// assuming pure virtual functions do not have definitions): // assuming pure virtual functions do not have definitions);
// also, do not automatically rewrite functions that could
// implicitly override depend base functions (and thus stop
// doing so after the rewrite; note that this is less
// dangerous for return types than for parameter types,
// where the function would still implicitly override and
// cause a compilation error due to the incompatible return
// type):
if (fullMode_ if (fullMode_
&& !((compat::isInMainFile( && !((compat::isInMainFile(
compiler.getSourceManager(), compiler.getSourceManager(),
...@@ -335,12 +344,18 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) { ...@@ -335,12 +344,18 @@ bool SalBool::VisitParmVarDecl(ParmVarDecl const * decl) {
decl->getDeclContext()) decl->getDeclContext())
->getNameInfo().getLoc())) ->getNameInfo().getLoc()))
|| f->isDefined() || f->isPure()) || f->isDefined() || f->isPure())
&& rewrite(loc))) && k != OverrideKind::MAYBE && rewrite(loc)))
{ {
report( report(
DiagnosticsEngine::Warning, DiagnosticsEngine::Warning,
"ParmVarDecl, use \"bool\" instead of \"sal_Bool\"", ("ParmVarDecl, use \"bool\" instead of"
" \"sal_Bool\"%0"),
loc) loc)
<< (k == OverrideKind::MAYBE
? (" (unless this member function overrides a"
" dependent base member function, even"
" though it is not marked 'override')")
: "")
<< decl->getSourceRange(); << decl->getSourceRange();
} }
} }
...@@ -437,12 +452,8 @@ bool SalBool::VisitFunctionDecl(FunctionDecl const * decl) { ...@@ -437,12 +452,8 @@ bool SalBool::VisitFunctionDecl(FunctionDecl const * decl) {
} }
if (isSalBool(compat::getReturnType(*decl).getNonReferenceType())) { if (isSalBool(compat::getReturnType(*decl).getNonReferenceType())) {
FunctionDecl const * f = decl->getCanonicalDecl(); FunctionDecl const * f = decl->getCanonicalDecl();
CXXMethodDecl const * m = dyn_cast<CXXMethodDecl>(f); OverrideKind k = getOverrideKind(f);
//XXX: canOverrideTemplateArgumentMember(m) does not require if (k != OverrideKind::YES
// !m->isVirtual()
if ((m == nullptr || !m->isVirtual()
|| (m->size_overridden_methods() == 0
&& !canOverrideTemplateArgumentMember(m)))
&& !(hasCLanguageLinkageType(f) && !(hasCLanguageLinkageType(f)
|| (isInUnoIncludeFile( || (isInUnoIncludeFile(
compiler.getSourceManager().getSpellingLoc( compiler.getSourceManager().getSpellingLoc(
...@@ -484,7 +495,13 @@ bool SalBool::VisitFunctionDecl(FunctionDecl const * decl) { ...@@ -484,7 +495,13 @@ bool SalBool::VisitFunctionDecl(FunctionDecl const * decl) {
{ {
report( report(
DiagnosticsEngine::Warning, DiagnosticsEngine::Warning,
"use \"bool\" instead of \"sal_Bool\" as return type", loc) "use \"bool\" instead of \"sal_Bool\" as return type%0",
loc)
<< (k == OverrideKind::MAYBE
? (" (unless this member function overrides a dependent"
" base member function, even though it is not marked"
" 'override')")
: "")
<< decl->getSourceRange(); << decl->getSourceRange();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment