improve loplugin:pointerbool

to look through template instantiations involving std::forward

motivated by
    commit b1617acde1
    drop RadioButton arg defaults
    the nBits arg in builder.cxx was in the wrong place

Change-Id: I222ea2aeea6f44ae54839e824a247a8105392c2d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109789
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel
2021-01-22 13:59:23 +02:00
committed by Noel Grandin
parent 9043ab3236
commit 6907cbb897
3 changed files with 52 additions and 1 deletions

View File

@ -38,12 +38,42 @@ public:
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
bool shouldVisitTemplateInstantiations() const { return true; }
bool PreTraverseFunctionDecl(FunctionDecl* decl);
bool PostTraverseFunctionDecl(FunctionDecl* decl, bool);
bool TraverseFunctionDecl(FunctionDecl* decl);
bool VisitCallExpr(CallExpr const*);
private:
llvm::Optional<APSInt> getCallValue(const Expr* arg);
std::vector<FunctionDecl*> functions_;
};
bool PointerBool::PreTraverseFunctionDecl(FunctionDecl* decl)
{
functions_.push_back(decl);
return true;
}
bool PointerBool::PostTraverseFunctionDecl(FunctionDecl*, bool)
{
assert(!functions_.empty());
functions_.pop_back();
return true;
}
bool PointerBool::TraverseFunctionDecl(FunctionDecl* decl)
{
bool ret = true;
if (PreTraverseFunctionDecl(decl))
{
ret = FilteringPlugin::TraverseFunctionDecl(decl);
PostTraverseFunctionDecl(decl, ret);
}
return ret;
}
bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
{
if (ignoreLocation(callExpr))
@ -98,6 +128,13 @@ bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
<< arg->getSourceRange();
report(DiagnosticsEngine::Note, "method here", param->getLocation())
<< param->getSourceRange();
if (!functions_.empty())
{
auto callerFD = functions_.back();
if (callerFD->isTemplateInstantiation())
report(DiagnosticsEngine::Note, "instantiated from here",
callerFD->getPointOfInstantiation());
}
}
return true;
}

View File

@ -29,4 +29,18 @@ void test1(int* p1)
func_bool(aSeq[0]);
}
void func_bool2(bool); // expected-note {{method here [loplugin:pointerbool]}}
template <typename... Args> void func_bool_via_forward_template(Args&&... args)
{
// expected-error@+1 {{possibly unwanted implicit conversion when calling bool param [loplugin:pointerbool]}}
func_bool2(std::forward<Args>(args)...);
}
void test2(int p1)
{
// expected-note@+1 {{instantiated from here [loplugin:pointerbool]}}
func_bool_via_forward_template(p1);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -366,7 +366,7 @@ void StringHelper::appendValue( OUStringBuffer& rStr, Type nData, FormatType eFm
case FORMATTYPE_SHORTHEX: appendShortHex( rStr, nData ); break;
case FORMATTYPE_BIN: appendBin( rStr, nData ); break;
case FORMATTYPE_FIX: appendFix( rStr, nData ); break;
case FORMATTYPE_BOOL: appendBool( rStr, nData ); break;
case FORMATTYPE_BOOL: appendBool( rStr, static_cast<bool>(nData) ); break; // avoid loplugin:pointerbool warning
default:;
}
}