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)) returntrue; // TODO this doesn't currently work, the args and the params don't seem to line up if (isa<CXXOperatorCallExpr>(callExpr)) returntrue; const FunctionDecl* functionDecl; if (isa<CXXMemberCallExpr>(callExpr))
{
functionDecl = dyn_cast<CXXMemberCallExpr>(callExpr)->getMethodDecl();
} else
{
functionDecl = callExpr->getDirectCallee();
} if (!functionDecl) returntrue;
unsigned len = std::min(callExpr->getNumArgs(), functionDecl->getNumParams()); for (unsigned i = 0; i < len; ++i)
{ auto param = functionDecl->getParamDecl(i); auto paramTC = loplugin::TypeCheck(param->getType()); if (!paramTC.AnyBoolean()) continue; auto arg = callExpr->getArg(i)->IgnoreImpCasts(); auto argTC = loplugin::TypeCheck(arg->getType()); if (argTC.AnyBoolean()) continue; // sal_Bool is sometimes disguised if (isa<SubstTemplateTypeParmType>(arg->getType())) if (arg->getType()->getUnqualifiedDesugaredType()->isSpecificBuiltinType(
clang::BuiltinType::UChar)) continue; if (arg->getType()->isDependentType()) continue; if (arg->getType()->isIntegerType())
{ auto ret = getCallValue(arg); if (compat::has_value(ret) && (compat::value(ret) == 1 || compat::value(ret) == 0)) continue; // something like: priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD if (isa<BinaryOperator>(arg->IgnoreParenImpCasts())) continue; // something like: pbEmbolden ? FcTrue : FcFalse if (isa<ConditionalOperator>(arg->IgnoreParenImpCasts())) continue;
}
report(DiagnosticsEngine::Warning, "possibly unwanted implicit conversion when calling bool param", arg->getExprLoc())
<< 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());
}
} returntrue;
}
compat::optional<APSInt> PointerBool::getCallValue(const Expr* arg)
{
arg = arg->IgnoreParenCasts(); if (auto defArg = dyn_cast<CXXDefaultArgExpr>(arg))
{
arg = defArg->getExpr()->IgnoreParenCasts();
} // ignore this, it seems to trigger an infinite recursion if (isa<UnaryExprOrTypeTraitExpr>(arg))
{ return compat::optional<APSInt>();
}
APSInt x1; if (compat::EvaluateAsInt(arg, x1, compiler.getASTContext()))
{ return x1;
} return compat::optional<APSInt>();
}
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.