void QStringArg::VisitStmt()

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");
    }
}