in src/checks/level0/qstring-arg.cpp [193:258]
void QStringArg::VisitStmt(clang::Stmt *stmt)
{
auto *memberCall = dyn_cast<CXXMemberCallExpr>(stmt);
if (!memberCall) {
return;
}
if (shouldIgnoreFile(stmt->getBeginLoc())) {
return;
}
checkForMultiArgOpportunities(memberCall);
if (checkQLatin1StringCase(memberCall)) {
return;
}
if (!isOptionSet("fillChar-overloads")) {
return;
}
CXXMethodDecl *method = isArgMethod(memberCall->getDirectCallee(), "QString");
if (!method) {
return;
}
if (clazy::simpleArgTypeName(method, method->getNumParams() - 1, lo()) == "QChar") {
// The second arg wasn't passed, so this is a safe and unambiguous use, like .arg(1)
if (isa<CXXDefaultArgExpr>(memberCall->getArg(1))) {
return;
}
const ParmVarDecl *p = method->getParamDecl(2);
if (p && clazy::name(p) == "base") {
// User went through the trouble specifying a base, lets allow it if it's a literal.
std::vector<IntegerLiteral *> literals;
clazy::getChilds<IntegerLiteral>(memberCall->getArg(2), literals);
if (!literals.empty()) {
return;
}
std::string variableName = clazy::toLower(variableNameFromArg(memberCall->getArg(2)));
if (clazy::contains(variableName, "base")) {
return;
}
}
p = method->getParamDecl(1);
if (p && clazy::name(p) == "fieldWidth") {
// He specified a literal, so he knows what he's doing, otherwise he would have put it directly in the string
std::vector<IntegerLiteral *> literals;
clazy::getChilds<IntegerLiteral>(memberCall->getArg(1), literals);
if (!literals.empty()) {
return;
}
// the variable is named "width", user knows what he's doing
std::string variableName = clazy::toLower(variableNameFromArg(memberCall->getArg(1)));
if (clazy::contains(variableName, "width")) {
return;
}
}
emitWarning(stmt->getBeginLoc(), "Using QString::arg() with fillChar overload");
}
}