void UseStaticQRegularExpression::VisitStmt()

in src/checks/level0/use-static-qregularexpression.cpp [162:238]


void UseStaticQRegularExpression::VisitStmt(clang::Stmt *stmt)
{
    if (!stmt) {
        return;
    }

    auto *method = dyn_cast_or_null<CXXMemberCallExpr>(stmt);
    if (!method) {
        return;
    }

    if (method->getNumArgs() == 0) {
        return;
    }

    auto *methodDecl = method->getMethodDecl();
    if (!methodDecl || !methodDecl->getDeclName().isIdentifier()) {
        return;
    }

    if (!isOfAcceptableType(methodDecl)) {
        return;
    }

    // QRegularExpression.match()
    const auto methodName = methodDecl->getName();
    if (methodName == "match" || methodName == "globalMatch") {
        auto *obj = method->getImplicitObjectArgument()->IgnoreImpCasts();
        if (!obj) {
            return;
        }

        if (obj->isLValue()) {
            if (isArgNonStaticLocalVar(obj, lo())) {
                emitWarning(obj->getBeginLoc(), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead");
                return;
            }

            // In clang20, "auto m2 = QRegularExpression("[123]").globalMatch(selectedText);" is apparently an l-value
            if (auto *temp = dyn_cast<MaterializeTemporaryExpr>(obj); temp && isTemporaryQRegexObj(temp, lo())) {
                emitWarning(temp->getBeginLoc(), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead");
            }

        } else if (obj->isXValue()) {
            // is it a temporary?
            auto *temp = dyn_cast<MaterializeTemporaryExpr>(obj);
            if (!temp) {
                return;
            }
            if (isTemporaryQRegexObj(temp, lo())) {
                emitWarning(temp->getBeginLoc(), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead");
            }
        }
        return;
    }

    if (!firstArgIsQRegularExpression(methodDecl, lo())) {
        return;
    }

    Expr *qregexArg = method->getArg(0);
    if (!qregexArg) {
        return;
    }

    // Its a QString*().method(QRegularExpression(arg)) ?
    if (auto *temp = isArgTemporaryObj(qregexArg)) {
        if (isTemporaryQRegexObj(temp, lo())) {
            emitWarning(qregexArg->getBeginLoc(), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead");
        }
    }

    // Its a local QRegularExpression variable?
    if (isArgNonStaticLocalVar(qregexArg, lo())) {
        emitWarning(qregexArg->getBeginLoc(), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead");
    }
}