diff --git a/CheckSources.generated.cmake b/CheckSources.generated.cmake index 1f30d8410..5cff22bfd 100644 --- a/CheckSources.generated.cmake +++ b/CheckSources.generated.cmake @@ -14,7 +14,6 @@ set(CLAZY_CHECKS_SRCS ${CLAZY_CHECKS_SRCS} ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qstring-varargs.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt-keyword-emit.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt-keywords.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt4-qstring-from-array.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt6-deprecated-api-fixes.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt6-fwd-fixes.cpp ${CMAKE_CURRENT_LIST_DIR}/src/checks/manuallevel/qt6-header-fixes.cpp diff --git a/ClazyTests.generated.cmake b/ClazyTests.generated.cmake index b13ca4581..eac7e3356 100644 --- a/ClazyTests.generated.cmake +++ b/ClazyTests.generated.cmake @@ -20,7 +20,6 @@ add_clazy_test(qrequiredresult-candidates) add_clazy_test(qstring-varargs) add_clazy_test(qt-keyword-emit) add_clazy_test(qt-keywords) -add_clazy_test(qt4-qstring-from-array) add_clazy_test(qt6-deprecated-api-fixes) add_clazy_test(qt6-fwd-fixes) add_clazy_test(qt6-header-fixes) diff --git a/HOWTO b/HOWTO index 7037cdd93..beff260c3 100644 --- a/HOWTO +++ b/HOWTO @@ -58,7 +58,6 @@ Tips for fixits functionargsbyref.cpp autounexpectedqstringbuilder.cpp qstringref.cpp - qt4-qstring-from-array.cpp -------------------------------------------------------------------------------- Running tests diff --git a/README.md b/README.md index d94b63079..820b088f5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ Table of contents * [clazy-standalone and JSON database support](#clazy-standalone-and-json-database-support) * [Enabling Fixits](#enabling-fixits) * [Troubleshooting](#troubleshooting) - * [Qt4 compatibility mode](#qt4-compatibility-mode) * [Reducing warning noise](#reducing-warning-noise) * [Reporting bugs and wishes](#reporting-bugs-and-wishes) * [Authors](#authors) @@ -230,7 +229,6 @@ clazy runs all checks from level1 by default. - [qstring-varargs](docs/checks/README-qstring-varargs.md) - [qt-keyword-emit](docs/checks/README-qt-keyword-emit.md) (fix-qt-keyword-emit) - [qt-keywords](docs/checks/README-qt-keywords.md) (fix-qt-keywords) - - [qt4-qstring-from-array](docs/checks/README-qt4-qstring-from-array.md) (fix-qt4-qstring-from-array) - [qt6-deprecated-api-fixes](docs/checks/README-qt6-deprecated-api-fixes.md) (fix-qt6-deprecated-api-fixes) - [qt6-fwd-fixes](docs/checks/README-qt6-fwd-fixes.md) (fix-qt6-fwd-fixes) - [qt6-header-fixes](docs/checks/README-qt6-header-fixes.md) (fix-qt6-header-fixes) @@ -432,16 +430,6 @@ with each other modifying the same source lines. If you're building in 32-bit, open clazy-cl.bat and insert a -m32 argument. Should read: %~dp0\clang\clang.exe –driver-mode=cl -m32 (...) -# Qt4 compatibility mode - -When running on codebases that must still compile with Qt4, you can pass `--qt4compat` -(a convenience option equivalent to passing `-Xclang -plugin-arg-clazy -Xclang qt4-compat`) -to disable checks that only make sense with Qt5. - -For example, to build a CMake project with Qt4 compatibility use: - `CXX="clazy --qt4compat"; cmake .` -and rebuild. - # Reducing warning noise If you think you found a false-positive, file a bug report. But do make sure to test first without icecc/distcc enabled. diff --git a/checks.json b/checks.json index 1c334affe..f0704c234 100644 --- a/checks.json +++ b/checks.json @@ -1,5 +1,5 @@ { - "available_categories" : ["readability", "qt4", "qt6", "containers", "qstring", "cpp", "bug", "performance", "deprecation", "qml"], + "available_categories" : ["readability", "qt6", "containers", "qstring", "cpp", "bug", "performance", "deprecation", "qml"], "checks" : [ { "name" : "qt-keywords", @@ -66,18 +66,6 @@ "categories" : ["bug"], "visits_stmts" : true }, - { - "name" : "qt4-qstring-from-array", - "class_name" : "Qt4QStringFromArray", - "level" : -1, - "categories" : ["qt4", "qstring"], - "fixits" : [ - { - "name" : "qt4-qstring-from-array" - } - ], - "visits_stmts" : true - }, { "name" : "qt6-qlatin1stringchar-to-u", "class_name" : "Qt6QLatin1StringCharToU", diff --git a/clazy.cmake b/clazy.cmake index 96e146407..d72e918f6 100644 --- a/clazy.cmake +++ b/clazy.cmake @@ -20,8 +20,6 @@ HELP() { echo "Any of the options above will print the requested information and then exit." echo echo "Convenience Options:" - echo " --qt4compat Qt4 compatibility mode. useful for source code that can build with Qt4" - echo " (this is the same as passing \"-Xclang -plugin-arg-clazy -Xclang qt4-compat\")" echo " --qtdeveloper Special option for building Qt5 itself resulting in fewer false positives" echo " (this is the same as passing \"-Xclang -plugin-arg-clazy -Xclang qt-developer\")" echo @@ -100,11 +98,6 @@ then fi ExtraClangOptions="" -if ( test $# -gt 0 -a "$1" = "--qt4compat" ) -then - shift - ExtraClangOptions="-Xclang -plugin-arg-clazy -Xclang qt4-compat" -fi if ( test $# -gt 0 -a "$1" = "--qtdeveloper" ) then shift diff --git a/dev-scripts/generate.py b/dev-scripts/generate.py index c0ceb4d79..2678aaba7 100755 --- a/dev-scripts/generate.py +++ b/dev-scripts/generate.py @@ -123,10 +123,6 @@ def readme_name(self): def readme_path(self): return docs_path() + self.readme_name() - - def supportsQt4(self): - return self.minimum_qt_version < 50000 - def get_class_name(self): if self.class_name: return self.class_name @@ -259,21 +255,18 @@ def generate_register_checks(checks): """ for c in checks: - qt4flag = "RegisteredCheck::Option_None" - if not c.supportsQt4(): - qt4flag = "RegisteredCheck::Option_Qt4Incompatible" - + qtflags = "RegisteredCheck::Option_None" if c.visits_stmts: - qt4flag += " | RegisteredCheck::Option_VisitsStmts" + qtflags += " | RegisteredCheck::Option_VisitsStmts" if c.visits_decls: - qt4flag += " | RegisteredCheck::Option_VisitsDecls" + qtflags += " | RegisteredCheck::Option_VisitsDecls" - qt4flag = qt4flag.replace("RegisteredCheck::Option_None |", "") + qtflags = qtflags.replace("RegisteredCheck::Option_None |", "") if c.ifndef: text += "#ifndef " + c.ifndef + "\n" - text += ' registerCheck(check<%s>("%s", %s, %s));\n' % (c.get_class_name(), c.name, level_num_to_enum(c.level), qt4flag) + text += ' registerCheck(check<%s>("%s", %s, %s));\n' % (c.get_class_name(), c.name, level_num_to_enum(c.level), qtflags) fixitID = 1 for fixit in c.fixits: diff --git a/docs/checks/README-qt4-qstring-from-array.md b/docs/checks/README-qt4-qstring-from-array.md deleted file mode 100644 index 783391402..000000000 --- a/docs/checks/README-qt4-qstring-from-array.md +++ /dev/null @@ -1,4 +0,0 @@ -# qt4-qstring-from-array - -Warns when using `QString` methods taking a `char*` or a `QByteArray`. -These are dangerous in Qt4 because Qt4 assumes they are in latin1, while Qt5 assumes they are in utf8. diff --git a/docs/man/clazy.pod b/docs/man/clazy.pod index 6d6fb8d7e..7a91118d5 100644 --- a/docs/man/clazy.pod +++ b/docs/man/clazy.pod @@ -47,19 +47,6 @@ Any of the options above will print the requested information and then exit. =over 4 -=item B<--qt4compat> - -This option runs clazy in Qt4 compatibility mode. -Use this when your source code can build with Qt4 and Qt5 in order to easily -suppress issues that cannot be fixed due to the requirement of the Qt4 API. - -This is a convenience option which is identical to directly passing: - "-Xclang -plugin-arg-clazy -Xclang qt4-compat" - -=back - -=over 4 - =item B<--qtdeveloper> B This option is special for running clazy on Qt itself. diff --git a/readmes.cmake b/readmes.cmake index 8c1022496..0612058ff 100644 --- a/readmes.cmake +++ b/readmes.cmake @@ -12,7 +12,6 @@ SET(README_manuallevel_FILES ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qstring-varargs.md ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt-keyword-emit.md ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt-keywords.md - ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt4-qstring-from-array.md ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt6-deprecated-api-fixes.md ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt6-fwd-fixes.md ${CMAKE_CURRENT_LIST_DIR}/docs/checks/README-qt6-header-fixes.md diff --git a/src/Checks.h b/src/Checks.h index c98443383..fc01c3656 100644 --- a/src/Checks.h +++ b/src/Checks.h @@ -91,7 +91,6 @@ #include "checks/manuallevel/qstring-varargs.h" #include "checks/manuallevel/qt-keyword-emit.h" #include "checks/manuallevel/qt-keywords.h" -#include "checks/manuallevel/qt4-qstring-from-array.h" #include "checks/manuallevel/qt6-deprecated-api-fixes.h" #include "checks/manuallevel/qt6-fwd-fixes.h" #include "checks/manuallevel/qt6-header-fixes.h" @@ -136,8 +135,6 @@ void CheckManager::registerChecks() registerFixIt(1, "fix-qt-keyword-emit", "qt-keyword-emit"); registerCheck(check("qt-keywords", ManualCheckLevel, RegisteredCheck::Option_None)); registerFixIt(1, "fix-qt-keywords", "qt-keywords"); - registerCheck(check("qt4-qstring-from-array", ManualCheckLevel, RegisteredCheck::Option_VisitsStmts)); - registerFixIt(1, "fix-qt4-qstring-from-array", "qt4-qstring-from-array"); registerCheck( check("qt6-deprecated-api-fixes", ManualCheckLevel, RegisteredCheck::Option_VisitsStmts | RegisteredCheck::Option_VisitsDecls)); registerFixIt(1, "fix-qt6-deprecated-api-fixes", "qt6-deprecated-api-fixes"); @@ -165,7 +162,7 @@ void CheckManager::registerChecks() registerCheck(check("use-arrow-operator-instead-of-data", ManualCheckLevel, RegisteredCheck::Option_VisitsStmts)); registerCheck(check("use-chrono-in-qtimer", ManualCheckLevel, RegisteredCheck::Option_VisitsStmts)); registerCheck(check("connect-by-name", CheckLevel0, RegisteredCheck::Option_VisitsDecls)); - registerCheck(check("connect-non-signal", CheckLevel0, RegisteredCheck::Option_Qt4Incompatible | RegisteredCheck::Option_VisitsStmts)); + registerCheck(check("connect-non-signal", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check("connect-not-normalized", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check("container-anti-pattern", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerCheck(check("empty-qstringliteral", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); @@ -183,10 +180,10 @@ void CheckManager::registerChecks() #endif registerCheck(check("qdatetime-utc", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerFixIt(1, "fix-qdatetime-utc", "qdatetime-utc"); - registerCheck(check("qenums", CheckLevel0, RegisteredCheck::Option_Qt4Incompatible)); + registerCheck(check("qenums", CheckLevel0, RegisteredCheck::Option_None)); registerCheck(check("qfileinfo-exists", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerFixIt(1, "fix-qfileinfo-exists", "qfileinfo-exists"); - registerCheck(check("qgetenv", CheckLevel0, RegisteredCheck::Option_Qt4Incompatible | RegisteredCheck::Option_VisitsStmts)); + registerCheck(check("qgetenv", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); registerFixIt(1, "fix-qgetenv", "qgetenv"); registerCheck(check("qmap-with-pointer-key", CheckLevel0, RegisteredCheck::Option_VisitsDecls)); registerCheck(check("qstring-arg", CheckLevel0, RegisteredCheck::Option_VisitsStmts)); @@ -240,9 +237,9 @@ void CheckManager::registerChecks() registerCheck(check("missing-qobject-macro", CheckLevel2, RegisteredCheck::Option_VisitsDecls)); registerFixIt(1, "fix-missing-qobject-macro", "missing-qobject-macro"); registerCheck(check("missing-typeinfo", CheckLevel2, RegisteredCheck::Option_VisitsDecls)); - registerCheck(check("old-style-connect", CheckLevel2, RegisteredCheck::Option_Qt4Incompatible | RegisteredCheck::Option_VisitsStmts)); + registerCheck(check("old-style-connect", CheckLevel2, RegisteredCheck::Option_VisitsStmts)); registerFixIt(1, "fix-old-style-connect", "old-style-connect"); - registerCheck(check("qstring-allocations", CheckLevel2, RegisteredCheck::Option_Qt4Incompatible | RegisteredCheck::Option_VisitsStmts)); + registerCheck(check("qstring-allocations", CheckLevel2, RegisteredCheck::Option_VisitsStmts)); registerFixIt(1, "fix-qlatin1string-allocations", "qstring-allocations"); registerFixIt(2, "fix-fromLatin1_fromUtf8-allocations", "qstring-allocations"); registerFixIt(4, "fix-fromCharPtrAllocations", "qstring-allocations"); diff --git a/src/Clazy.cpp b/src/Clazy.cpp index 00c727065..7a8e0ac34 100644 --- a/src/Clazy.cpp +++ b/src/Clazy.cpp @@ -242,10 +242,6 @@ bool ClazyASTAction::ParseArgs(const CompilerInstance &ci, const std::vector lock(CheckManager::lock()); - m_checks = m_checkManager->requestedChecks(args, m_options & ClazyContext::ClazyOption_Qt4Compat); + m_checks = m_checkManager->requestedChecks(args); } if (args.size() > 1) { @@ -397,8 +393,7 @@ std::unique_ptr ClazyStandaloneASTAction::CreateASTConsumer(Compile std::vector checks; checks.push_back(m_checkList); - const bool qt4Compat = m_options & ClazyContext::ClazyOption_Qt4Compat; - const RegisteredCheck::List requestedChecks = cm->requestedChecks(checks, qt4Compat); + const RegisteredCheck::List requestedChecks = cm->requestedChecks(checks); if (requestedChecks.empty()) { llvm::errs() << "No checks were requested!\n" diff --git a/src/ClazyContext.h b/src/ClazyContext.h index 62080e740..ec0e10be1 100644 --- a/src/ClazyContext.h +++ b/src/ClazyContext.h @@ -45,7 +45,6 @@ class ClazyContext enum ClazyOption { ClazyOption_None = 0, ClazyOption_ExportFixes = 1, - ClazyOption_Qt4Compat = 2, ClazyOption_OnlyQt = 4, // Ignore non-Qt files. This is done by bailing out if QT_CORE_LIB is not set. ClazyOption_QtDeveloper = 8, // For running clazy on Qt itself, optional, but honours specific guidelines ClazyOption_VisitImplicitCode = 16, // Inspect compiler generated code aswell, useful for custom checks, if they need it diff --git a/src/ClazyStandaloneMain.cpp b/src/ClazyStandaloneMain.cpp index 985e32ae7..b84b44587 100644 --- a/src/ClazyStandaloneMain.cpp +++ b/src/ClazyStandaloneMain.cpp @@ -38,8 +38,6 @@ static cl::opt cl::init(""), cl::cat(s_clazyCategory)); -static cl::opt s_qt4Compat("qt4-compat", cl::desc("Turns off checks not compatible with Qt 4"), cl::init(false), cl::cat(s_clazyCategory)); - static cl::opt s_onlyQt("only-qt", cl::desc("Won't emit warnings for non-Qt files, or in other words, if -DQT_CORE_LIB is missing."), cl::init(false), @@ -113,10 +111,6 @@ class ClazyToolActionFactory : public clang::tooling::FrontendActionFactory options |= ClazyContext::ClazyOption_ExportFixes; } - if (s_qt4Compat.getValue()) { - options |= ClazyContext::ClazyOption_Qt4Compat; - } - if (s_qtDeveloper.getValue()) { options |= ClazyContext::ClazyOption_QtDeveloper; } @@ -188,7 +182,7 @@ int main(int argc, const char **argv) if (s_listEnabledChecks.getValue()) { std::string checksFromArgs = s_checks.getValue(); std::vector checks = {checksFromArgs.empty() ? "level1" : checksFromArgs}; - const RegisteredCheck::List enabledChecks = CheckManager::instance()->requestedChecks(checks, s_qt4Compat.getValue()); + const RegisteredCheck::List enabledChecks = CheckManager::instance()->requestedChecks(checks); if (!enabledChecks.empty()) { llvm::outs() << "Enabled checks:"; diff --git a/src/checkmanager.cpp b/src/checkmanager.cpp index f5b969ff4..b72812ce5 100644 --- a/src/checkmanager.cpp +++ b/src/checkmanager.cpp @@ -157,7 +157,7 @@ static bool takeArgument(const std::string &arg, std::vector &args) return false; } -RegisteredCheck::List CheckManager::requestedChecks(std::vector &args, bool qt4Compat) +RegisteredCheck::List CheckManager::requestedChecks(std::vector &args) { RegisteredCheck::List result; @@ -200,16 +200,6 @@ RegisteredCheck::List CheckManager::requestedChecks(std::vector &ar clazy::sort_and_remove_dups(result, checkLessThan); CheckManager::removeChecksFromList(result, userDisabledChecks); - if (qt4Compat) { - // #5 Remove Qt4 incompatible checks - result.erase(remove_if(result.begin(), - result.end(), - [](const RegisteredCheck &c) { - return c.options & RegisteredCheck::Option_Qt4Incompatible; - }), - result.end()); - } - return result; } diff --git a/src/checkmanager.h b/src/checkmanager.h index b6015025d..d64d3e65c 100644 --- a/src/checkmanager.h +++ b/src/checkmanager.h @@ -45,7 +45,7 @@ struct RegisteredFixIt { using FactoryFunction = std::function; struct RegisteredCheck { - enum Option { Option_None = 0, Option_Qt4Incompatible = 1, Option_VisitsStmts = 2, Option_VisitsDecls = 4 }; + enum Option { Option_None = 0, Option_VisitsStmts = 2, Option_VisitsDecls = 4 }; using List = std::vector; using Options = int; @@ -101,7 +101,7 @@ class CheckManager * Returns all the requested checks. * This is a union of the requested checks via env variable and via arguments passed to compiler */ - RegisteredCheck::List requestedChecks(std::vector &args, bool qt4Compat); + RegisteredCheck::List requestedChecks(std::vector &args); std::vector> createChecks(const RegisteredCheck::List &requestedChecks, ClazyContext *context); static void removeChecksFromList(RegisteredCheck::List &list, std::vector &checkNames); diff --git a/src/checks/manuallevel/qt4-qstring-from-array.cpp b/src/checks/manuallevel/qt4-qstring-from-array.cpp deleted file mode 100644 index 5d7dbfce1..000000000 --- a/src/checks/manuallevel/qt4-qstring-from-array.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - SPDX-FileCopyrightText: 2015 Klarälvdalens Datakonsult AB a KDAB Group company info@kdab.com - SPDX-FileContributor: Sérgio Martins - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "qt4-qstring-from-array.h" -#include "ClazyContext.h" -#include "FixItUtils.h" -#include "HierarchyUtils.h" -#include "StringUtils.h" -#include "Utils.h" -#include "clazy_stl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace clang; - -Qt4QStringFromArray::Qt4QStringFromArray(const std::string &name, ClazyContext *context) - : CheckBase(name, context, Option_CanIgnoreIncludes) -{ -} - -static bool isInterestingParam(ParmVarDecl *param, bool &is_char_array, bool &is_byte_array) -{ - is_char_array = false; - is_byte_array = false; - const std::string typeStr = param->getType().getAsString(); - if (typeStr == "const class QByteArray &") { - is_byte_array = true; - } else if (typeStr == "const char *") { // We only want bytearray and const char* - is_char_array = true; - } - - return is_char_array || is_byte_array; -} - -static bool isInterestingCtorCall(CXXConstructorDecl *ctor, bool &is_char_array, bool &is_byte_array) -{ - is_char_array = false; - is_byte_array = false; - if (!ctor || !clazy::isOfClass(ctor, "QString")) { - return false; - } - - for (auto *param : Utils::functionParameters(ctor)) { - if (isInterestingParam(param, is_char_array, is_byte_array)) { - break; - } - - return false; - } - - return is_char_array || is_byte_array; -} - -static bool isInterestingMethod(const std::string &methodName) -{ - static const std::vector methods = - {"append", "prepend", "operator=", "operator==", "operator!=", "operator<", "operator<=", "operator>", "operator>=", "operator+="}; - return clazy::contains(methods, methodName); -} - -static bool isInterestingMethodCall(CXXMethodDecl *method, std::string &methodName, bool &is_char_array, bool &is_byte_array) -{ - is_char_array = false; - is_byte_array = false; - if (!method) { - return false; - } - - if (clazy::name(method->getParent()) != "QString" || method->getNumParams() != 1) { - return false; - } - - methodName = method->getNameAsString(); - if (!isInterestingMethod(methodName)) { - return false; - } - - if (!isInterestingParam(method->getParamDecl(0), is_char_array, is_byte_array)) { - return false; - } - - return true; -} - -static bool isInterestingOperatorCall(CXXOperatorCallExpr *op, std::string &operatorName, bool &is_char_array, bool &is_byte_array) -{ - is_char_array = false; - is_byte_array = false; - FunctionDecl *func = op->getDirectCallee(); - if (!func) { - return false; - } - - return isInterestingMethodCall(dyn_cast(func), operatorName, is_char_array, is_byte_array); -} - -void Qt4QStringFromArray::VisitStmt(clang::Stmt *stm) -{ - auto *ctorExpr = dyn_cast(stm); - auto *operatorCall = dyn_cast(stm); - auto *memberCall = dyn_cast(stm); - if (!ctorExpr && !operatorCall && !memberCall) { - return; - } - - std::vector fixits; - bool is_char_array = false; - bool is_byte_array = false; - std::string methodName; - std::string message; - - if (ctorExpr) { - CXXConstructorDecl *ctorDecl = ctorExpr->getConstructor(); - - if (!isInterestingCtorCall(ctorDecl, is_char_array, is_byte_array)) { - return; - } - - fixits = fixCtorCall(ctorExpr); - if (is_char_array) { - message = "QString(const char *) ctor being called"; - } else { - message = "QString(QByteArray) ctor being called"; - } - } else if (operatorCall) { - if (!isInterestingOperatorCall(operatorCall, /*by-ref*/ methodName, is_char_array, is_byte_array)) { - return; - } - - fixits = fixOperatorCall(operatorCall); - } else if (memberCall) { - if (!isInterestingMethodCall(memberCall->getMethodDecl(), /*by-ref*/ methodName, is_char_array, is_byte_array)) { - return; - } - - fixits = fixMethodCallCall(memberCall); - } else { - return; - } - - if (operatorCall || memberCall) { - if (is_char_array) { - message = "QString::" + methodName + "(const char *) being called"; - } else { - message = "QString::" + methodName + "(QByteArray) being called"; - } - } - - emitWarning(stm->getBeginLoc(), message, fixits); -} - -std::vector Qt4QStringFromArray::fixCtorCall(CXXConstructExpr *ctorExpr) -{ - Stmt *parent = clazy::parent(m_context->parentMap, ctorExpr); // CXXBindTemporaryExpr - Stmt *grandParent = clazy::parent(m_context->parentMap, parent); // CXXFunctionalCastExpr - - if (parent && grandParent && isa(parent) && isa(grandParent)) { - return fixitReplaceWithFromLatin1(ctorExpr); - } - return fixitInsertFromLatin1(ctorExpr); -} - -std::vector Qt4QStringFromArray::fixOperatorCall(CXXOperatorCallExpr *op) -{ - std::vector fixits; - if (op->getNumArgs() == 2) { - Expr *e = op->getArg(1); - SourceLocation start = e->getBeginLoc(); - SourceLocation end = Lexer::getLocForEndOfToken(clazy::biggestSourceLocationInStmt(sm(), e), 0, sm(), lo()); - - SourceRange range = {start, end}; - if (range.isInvalid()) { - emitWarning(op->getBeginLoc(), "internal error"); - return {}; - } - - clazy::insertParentMethodCall("QString::fromLatin1", {start, end}, /*by-ref*/ fixits); - - } else { - emitWarning(op->getBeginLoc(), "internal error"); - } - - return fixits; -} - -std::vector Qt4QStringFromArray::fixMethodCallCall(clang::CXXMemberCallExpr *memberExpr) -{ - std::vector fixits; - - if (memberExpr->getNumArgs() == 1) { - Expr *e = *(memberExpr->arg_begin()); - SourceLocation start = e->getBeginLoc(); - SourceLocation end = Lexer::getLocForEndOfToken(clazy::biggestSourceLocationInStmt(sm(), e), 0, sm(), lo()); - - SourceRange range = {start, end}; - if (range.isInvalid()) { - emitWarning(memberExpr->getBeginLoc(), "internal error"); - return {}; - } - - clazy::insertParentMethodCall("QString::fromLatin1", {start, end}, /*by-ref*/ fixits); - } else { - emitWarning(memberExpr->getBeginLoc(), "internal error"); - } - - return fixits; -} - -std::vector Qt4QStringFromArray::fixitReplaceWithFromLatin1(CXXConstructExpr *ctorExpr) -{ - const std::string replacement = "QString::fromLatin1"; - const std::string replacee = "QString"; - std::vector fixits; - - SourceLocation rangeStart = ctorExpr->getBeginLoc(); - SourceLocation rangeEnd = Lexer::getLocForEndOfToken(rangeStart, -1, sm(), lo()); - - if (rangeEnd.isInvalid()) { - // Fallback. Have seen a case in the wild where the above would fail, it's very rare - rangeEnd = rangeStart.getLocWithOffset(replacee.size() - 2); - if (rangeEnd.isInvalid()) { - clazy::printLocation(sm(), rangeStart); - clazy::printLocation(sm(), rangeEnd); - clazy::printLocation(sm(), Lexer::getLocForEndOfToken(rangeStart, 0, sm(), lo())); - queueManualFixitWarning(ctorExpr->getBeginLoc()); - return {}; - } - } - - fixits.push_back(FixItHint::CreateReplacement(SourceRange(rangeStart, rangeEnd), replacement)); - return fixits; -} - -std::vector Qt4QStringFromArray::fixitInsertFromLatin1(CXXConstructExpr *ctorExpr) -{ - std::vector fixits; - SourceRange range; - - Expr *arg = *(ctorExpr->arg_begin()); - range.setBegin(arg->getBeginLoc()); - range.setEnd(Lexer::getLocForEndOfToken(clazy::biggestSourceLocationInStmt(sm(), ctorExpr), 0, sm(), lo())); - if (range.isInvalid()) { - emitWarning(ctorExpr->getBeginLoc(), "Internal error"); - return {}; - } - - clazy::insertParentMethodCall("QString::fromLatin1", range, fixits); - - return fixits; -} diff --git a/src/checks/manuallevel/qt4-qstring-from-array.h b/src/checks/manuallevel/qt4-qstring-from-array.h deleted file mode 100644 index 0ef961ee7..000000000 --- a/src/checks/manuallevel/qt4-qstring-from-array.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - SPDX-FileCopyrightText: 2015 Klarälvdalens Datakonsult AB a KDAB Group company info@kdab.com - SPDX-FileContributor: Sérgio Martins - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef CLAZY_QT4_QSTRING_FROM_ARRAY_H -#define CLAZY_QT4_QSTRING_FROM_ARRAY_H - -#include "checkbase.h" - -#include -#include - -class ClazyContext; - -namespace clang -{ -class Stmt; -class FixItHint; -class CXXConstructExpr; -class CXXOperatorCallExpr; -class Expr; -class CXXMemberCallExpr; -} - -/** - * Replaces QString(char*) or QString(QByteArray) calls with QString::fromLatin1(). - * - * Run only in Qt 4 code. - */ -class Qt4QStringFromArray : public CheckBase -{ -public: - explicit Qt4QStringFromArray(const std::string &name, ClazyContext *context); - void VisitStmt(clang::Stmt *stmt) override; - -private: - std::vector fixCtorCall(clang::CXXConstructExpr *ctorExpr); - std::vector fixOperatorCall(clang::CXXOperatorCallExpr *ctorExpr); - std::vector fixMethodCallCall(clang::CXXMemberCallExpr *memberExpr); - std::vector fixitReplaceWithFromLatin1(clang::CXXConstructExpr *ctorExpr); - std::vector fixitInsertFromLatin1(clang::CXXConstructExpr *ctorExpr); -}; - -#endif diff --git a/src/checks/ruleofbase.cpp b/src/checks/ruleofbase.cpp index 43d560907..4d9ad62c4 100644 --- a/src/checks/ruleofbase.cpp +++ b/src/checks/ruleofbase.cpp @@ -51,8 +51,6 @@ bool RuleOfBase::isBlacklisted(CXXRecordDecl *record) const "QMutableListIterator", "QStringList", "QVariant::Private", - "QModelIndex", // Qt4 - "QPair", // Qt4 "QSet", // Fixed for Qt 5.7 "QSet::iterator", "QSet::const_iterator", diff --git a/tests/clazy/config.json b/tests/clazy/config.json index 055336cb6..db7724297 100644 --- a/tests/clazy/config.json +++ b/tests/clazy/config.json @@ -27,16 +27,6 @@ "checks" : ["qgetenv"], "env" : { "CLAZY_NO_WERROR" : "1" } }, - { - "filename" : "qt4compat1.cpp", - "checks" : ["old-style-connect"], - "has_fixits" : true - }, - { - "filename" : "qt4compat2.cpp", - "checks" : ["old-style-connect"], - "qt4compat": true - }, { "filename" : "onlyQt1.cpp", "checks" : ["old-style-connect"], diff --git a/tests/clazy/qt4compat1.cpp b/tests/clazy/qt4compat1.cpp deleted file mode 100644 index 4a85bb600..000000000 --- a/tests/clazy/qt4compat1.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void test() -{ - QObject o; - o.connect(&o, SIGNAL(foo()), SLOT(bar())); -} diff --git a/tests/clazy/qt4compat1.cpp.expected b/tests/clazy/qt4compat1.cpp.expected deleted file mode 100644 index 096ad9154..000000000 --- a/tests/clazy/qt4compat1.cpp.expected +++ /dev/null @@ -1,2 +0,0 @@ -clazy/qt4compat1.cpp:6:5: warning: Old Style Connect [-Wclazy-old-style-connect] -clazy/qt4compat1.cpp:6:19: warning: FixIt failed, requires manual intervention: No such method foo in class QObject [-Wclazy-old-style-connect] diff --git a/tests/clazy/qt4compat1.cpp.fixed.expected b/tests/clazy/qt4compat1.cpp.fixed.expected deleted file mode 100644 index 4a85bb600..000000000 --- a/tests/clazy/qt4compat1.cpp.fixed.expected +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void test() -{ - QObject o; - o.connect(&o, SIGNAL(foo()), SLOT(bar())); -} diff --git a/tests/clazy/qt4compat2.cpp b/tests/clazy/qt4compat2.cpp deleted file mode 100644 index 4a85bb600..000000000 --- a/tests/clazy/qt4compat2.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void test() -{ - QObject o; - o.connect(&o, SIGNAL(foo()), SLOT(bar())); -} diff --git a/tests/clazy/qt4compat2.cpp.expected b/tests/clazy/qt4compat2.cpp.expected deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/qt4-qstring-from-array/config.json b/tests/qt4-qstring-from-array/config.json deleted file mode 100644 index 7f5f68cde..000000000 --- a/tests/qt4-qstring-from-array/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "tests": [ - { - "filename": "main.cpp", - "qt_major_versions": [4], - "has_fixits": true - } - ] -} diff --git a/tests/qt4-qstring-from-array/main.cpp b/tests/qt4-qstring-from-array/main.cpp deleted file mode 100644 index aa17b857f..000000000 --- a/tests/qt4-qstring-from-array/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include - - - - -QByteArray returns_byte_array() { return {}; } -void receivesQString(const QString &) {} - - - - - - - -void test() -{ - QByteArray bytearray; - QString s1("test"); - QString s2(bytearray); - QString s3(bytearray + bytearray); - QString s4 = QString("test"); - QString s5 = QString(bytearray); - QString s6 = QString(bytearray + bytearray); - QString s7 = QString(); // OK - QString s8 = QString(QString()); // OK - s1 = "test"; - s1 = "test" - "bar"; - s1 = bytearray; - - if (s1 == "test") {} - if (s1 == bytearray) {} - if (s1 == bytearray + "test") {} - - s1 = bytearray + bytearray; - s1 += bytearray; - s1 += bytearray + bytearray; - s1.append("foo"); - s1.prepend(bytearray); - s1 = true ? "foo" : "bar"; - - QString s9(returns_byte_array() + bytearray); - s1.append(returns_byte_array()); - - receivesQString("test"); -} diff --git a/tests/qt4-qstring-from-array/main.cpp.expected b/tests/qt4-qstring-from-array/main.cpp.expected deleted file mode 100644 index bc42960da..000000000 --- a/tests/qt4-qstring-from-array/main.cpp.expected +++ /dev/null @@ -1,21 +0,0 @@ -qt4-qstring-from-array/main.cpp:19:13: warning: QString(const char *) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:20:13: warning: QString(QByteArray) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:21:13: warning: QString(QByteArray) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:22:18: warning: QString(const char *) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:23:18: warning: QString(QByteArray) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:24:18: warning: QString(QByteArray) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:27:5: warning: QString::operator=(const char *) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:28:5: warning: QString::operator=(const char *) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:30:5: warning: QString::operator=(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:32:9: warning: QString::operator==(const char *) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:33:9: warning: QString::operator==(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:34:9: warning: QString::operator==(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:36:5: warning: QString::operator=(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:37:5: warning: QString::operator+=(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:38:5: warning: QString::operator+=(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:39:5: warning: QString::append(const char *) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:40:5: warning: QString::prepend(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:41:5: warning: QString::operator=(const char *) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:43:13: warning: QString(QByteArray) ctor being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:44:5: warning: QString::append(QByteArray) being called [-Wclazy-qt4-qstring-from-array] -qt4-qstring-from-array/main.cpp:46:21: warning: QString(const char *) ctor being called [-Wclazy-qt4-qstring-from-array] diff --git a/tests/qt4-qstring-from-array/main.cpp.fixed.expected b/tests/qt4-qstring-from-array/main.cpp.fixed.expected deleted file mode 100644 index e5b0aaf7a..000000000 --- a/tests/qt4-qstring-from-array/main.cpp.fixed.expected +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include - - - - -QByteArray returns_byte_array() { return {}; } -void receivesQString(const QString &) {} - - - - - - - -void test() -{ - QByteArray bytearray; - QString s1(QString::fromLatin1("test")); - QString s2(QString::fromLatin1(bytearray)); - QString s3(QString::fromLatin1(bytearray + bytearray)); - QString s4 = QString::fromLatin1("test"); - QString s5 = QString::fromLatin1(bytearray); - QString s6 = QString::fromLatin1(bytearray + bytearray); - QString s7 = QString(); // OK - QString s8 = QString(QString()); // OK - s1 = QString::fromLatin1("test"); - s1 = QString::fromLatin1("test" - "bar"); - s1 = QString::fromLatin1(bytearray); - - if (s1 == QString::fromLatin1("test")) {} - if (s1 == QString::fromLatin1(bytearray)) {} - if (s1 == QString::fromLatin1(bytearray + "test")) {} - - s1 = QString::fromLatin1(bytearray + bytearray); - s1 += QString::fromLatin1(bytearray); - s1 += QString::fromLatin1(bytearray + bytearray); - s1.append(QString::fromLatin1("foo")); - s1.prepend(QString::fromLatin1(bytearray)); - s1 = QString::fromLatin1(true ? "foo" : "bar"); - - QString s9(QString::fromLatin1(returns_byte_array() + bytearray)); - s1.append(QString::fromLatin1(returns_byte_array())); - - receivesQString(QString::fromLatin1("test")); -} diff --git a/tests/run_tests.py b/tests/run_tests.py index c3547caf7..9fb9d5dce 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -79,7 +79,6 @@ def __init__(self, check): self.flags = "" self.must_fail = False self.blacklist_platforms = [] - self.qt4compat = False self.only_qt = False self.qt_developer = False self.header_filter = "" @@ -286,8 +285,6 @@ def load_json(check_name): test.has_fixits = t['has_fixits'] and test.minimum_clang_version_for_fixits <= CLANG_VERSION if 'expects_failure' in t: test.expects_failure = t['expects_failure'] - if 'qt4compat' in t: - test.qt4compat = t['qt4compat'] if 'only_qt' in t: test.only_qt = t['only_qt'] if 'cppStandards' in t: @@ -337,9 +334,8 @@ def find_qt_installation(major_version, qmakes): " using qmake " + qmake) break - if installation.int_version == 0 and major_version >= 5: # Don't warn for missing Qt4 headers - print("Error: Couldn't find a Qt" + - str(major_version) + " installation") + if installation.int_version == 0: + print("Error: Couldn't find a Qt" + str(major_version) + " installation") return installation @@ -387,9 +383,6 @@ def clazy_standalone_command(test, cppStandard, qt): result = " -export-fixes=" + \ test.yamlFilename(is_standalone=True) + result - if test.qt4compat: - result = " -qt4-compat " + result - if test.only_qt: result = " -only-qt " + result @@ -420,9 +413,6 @@ def clazy_command(test, cppStandard, qt, filename): result = clang_name() + " -Xclang -load -Xclang " + libraryName() + " -Xclang -add-plugin -Xclang clazy " result += clazy_cpp_args(cppStandard) + qt.compiler_flags(test.qt_modules_includes) + suppress_line_numbers_opt - if test.qt4compat: - result = result + " -Xclang -plugin-arg-clazy -Xclang qt4-compat " - if test.only_qt: result = result + " -Xclang -plugin-arg-clazy -Xclang only-qt " if test.qt_developer: @@ -495,8 +485,6 @@ def compiler_name(): 6, ["QT_SELECT=6 qmake", "qmake-qt6", "qmake", "qmake6"]) _qt5_installation = find_qt_installation( 5, ["QT_SELECT=5 qmake", "qmake-qt5", "qmake", "qmake5"]) -_qt4_installation = find_qt_installation( - 4, ["QT_SELECT=4 qmake", "qmake-qt4", "qmake"]) _excluded_checks = args.exclude.split(',') if args.exclude is not None else [] # ------------------------------------------------------------------------------- @@ -534,9 +522,6 @@ def qt_installation(major_version): return _qt6_installation elif major_version == 5: return _qt5_installation - elif major_version == 4: - return _qt4_installation - return None