diff options
author | Waqar Ahmed <waqar.ahmed@kdab.com> | 2021-07-28 14:01:51 +0500 |
---|---|---|
committer | Waqar Ahmed <waqar.17a@gmail.com> | 2021-07-28 14:02:10 +0500 |
commit | a20570c6757cbbc71900394c7667086555825701 (patch) | |
tree | e5b3a3b5cf4d0b6ff4d03727df69b216d4c7ab15 | |
parent | c929ad0a23d58737f1e39edc79fe671ad05f4c8e (diff) |
Fixes for use-static-qregular-expression
The check was warning on statements where the regex value is not known
e.g:
void fun(QString regex)
{
str.contains(QRegularExpression(regex)); // Should not warn
}
-rw-r--r-- | src/checks/level0/use-static-qregularexpression.cpp | 87 | ||||
-rw-r--r-- | tests/use-static-qregularexpression/main.cpp | 26 | ||||
-rw-r--r-- | tests/use-static-qregularexpression/main.cpp.expected | 26 |
3 files changed, 113 insertions, 26 deletions
diff --git a/src/checks/level0/use-static-qregularexpression.cpp b/src/checks/level0/use-static-qregularexpression.cpp index ce078ef0..30a2ea85 100644 --- a/src/checks/level0/use-static-qregularexpression.cpp +++ b/src/checks/level0/use-static-qregularexpression.cpp @@ -39,24 +39,72 @@ UseStaticQRegularExpression::UseStaticQRegularExpression(const std::string &name { } -static bool isArgNonStaticLocalVar(Expr *arg0) +static MaterializeTemporaryExpr* isArgTemporaryObj(Expr *arg0) { - auto declRefExpr = dyn_cast_or_null<DeclRefExpr>(clazy::getFirstChild(arg0)); + return dyn_cast_or_null<MaterializeTemporaryExpr>(arg0); +} + +static VarDecl* getVarDecl(Expr *arg) +{ + auto declRefExpr = dyn_cast_or_null<DeclRefExpr>(clazy::getFirstChild(arg)); if (!declRefExpr) { + return nullptr; + } + return dyn_cast_or_null<VarDecl>(declRefExpr->getDecl()); +} + +static Expr* getVarInitExpr(VarDecl *VDef) +{ + return VDef->getDefinition() ? VDef->getDefinition()->getInit() : nullptr; +} + +static bool isQStringFromStringLiteral(Expr *qstring) +{ + if (isArgTemporaryObj(qstring)) { + return true; + } + + if (auto *VD = getVarDecl(qstring)) { + auto *stringLit = clazy::getFirstChildOfType<StringLiteral>(getVarInitExpr(VD)); + if (stringLit) { + return true; + } + } + return false; +} + +static bool isQRegexpFromStringLiteral(VarDecl *qregexVarDecl) +{ + Expr *initExpr = getVarInitExpr(qregexVarDecl); + if (!initExpr) { return false; } - auto varDecl = dyn_cast_or_null<VarDecl>(declRefExpr->getDecl()); - if (!varDecl) { + auto ctorCall = dyn_cast_or_null<CXXConstructExpr>(*initExpr->child_begin()); + if (!ctorCall) { return false; } - return varDecl->isLocalVarDecl() && !varDecl->isStaticLocal(); + auto qstringArg = ctorCall->getArg(0); + if (qstringArg && isQStringFromStringLiteral(qstringArg)) { + return true; + } + + return false; } -static bool isArgTemporaryObj(Expr *arg0) +static bool isArgNonStaticLocalVar(Expr *qregexp) { - return dyn_cast_or_null<MaterializeTemporaryExpr>(arg0); + auto *varDecl = getVarDecl(qregexp); + if (!varDecl) { + return false; + } + + if (!isQRegexpFromStringLiteral(varDecl)) { + return false; + } + + return varDecl->isLocalVarDecl() && !varDecl->isStaticLocal(); } static bool isQStringOrQStringListMethod(CXXMethodDecl *methodDecl) @@ -92,18 +140,31 @@ void UseStaticQRegularExpression::VisitStmt(clang::Stmt *stmt) return; } - Expr* arg0 = method->getArg(0); - if (!arg0) { + Expr* qregexArg = method->getArg(0); + if (!qregexArg) { return; } - if (isArgTemporaryObj(arg0)) { - emitWarning(clazy::getLocStart(arg0), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead"); + // Its a QRegularExpression(arg) ? + if (auto temp = isArgTemporaryObj(qregexArg)) { + // Get the QRegularExpression ctor + auto ctor = clazy::getFirstChildOfType<CXXConstructExpr>(temp); + + // Check if its first arg is "QString" && a temporary OR non-static local + auto qstrArg = ctor->getArg(0); + if (!qstrArg || clazy::typeName(qstrArg->getType(), lo(), true) != "QString") { + return; + } + + if (isQStringFromStringLiteral(qstrArg)) { + emitWarning(clazy::getLocStart(qregexArg), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead"); + } return; } - if (isArgNonStaticLocalVar(arg0)) { - emitWarning(clazy::getLocStart(arg0), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead"); + // Its a local QRegularExpression variable? + if (isArgNonStaticLocalVar(qregexArg)) { + emitWarning(clazy::getLocStart(qregexArg), "Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead"); return; } } diff --git a/tests/use-static-qregularexpression/main.cpp b/tests/use-static-qregularexpression/main.cpp index 41e757d8..eaa63340 100644 --- a/tests/use-static-qregularexpression/main.cpp +++ b/tests/use-static-qregularexpression/main.cpp @@ -1,4 +1,3 @@ -#include <QtCore/QObject> #include <QtCore/QString> #include <QtCore/QRegularExpression> @@ -53,4 +52,29 @@ void test() strList.lastIndexOf(e); // Warn strList.lastIndexOf(staticRegex); // Ok + + QString regexStr = "[abc]"; + h.contains(QRegularExpression(regexStr)); // Warn + + { + QRegularExpression reg(regexStr); + h.contains(reg); // Warn + } + { + static const QRegularExpression reg(regexStr); + h.contains(reg); // Ok + } +} + +void test1(const QString& regex, QString toCheck) +{ + QRegularExpression re(regex); + toCheck.contains(re); // Ok +} + +void test2(const QStringList& regexes, QString toCheck) +{ + for (const auto& regix : regexes) { + toCheck.contains(QRegularExpression(regix)); // Ok, no warn + } } diff --git a/tests/use-static-qregularexpression/main.cpp.expected b/tests/use-static-qregularexpression/main.cpp.expected index a07a10e4..120a1557 100644 --- a/tests/use-static-qregularexpression/main.cpp.expected +++ b/tests/use-static-qregularexpression/main.cpp.expected @@ -1,19 +1,21 @@ -use-static-qregularexpression/main.cpp:7:33: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:11:24: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:14:24: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:6:33: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:10:24: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:13:24: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:20:19: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:21:19: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:22:19: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:24:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:25:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:26:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:28:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:29:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:30:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:32:14: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:33:14: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:34:14: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:36:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:37:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:38:15: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:40:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:41:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:42:13: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:44:16: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] use-static-qregularexpression/main.cpp:45:16: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:46:16: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:51:21: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] -use-static-qregularexpression/main.cpp:54:25: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:50:21: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:53:25: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:57:16: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] +use-static-qregularexpression/main.cpp:61:20: warning: Don't create temporary QRegularExpression objects. Use a static QRegularExpression object instead [-Wclazy-use-static-qregularexpression] |