diff --git a/src/checks/inefficientqlistbase.cpp b/src/checks/inefficientqlistbase.cpp index 51fb104..d75a242 100644 --- a/src/checks/inefficientqlistbase.cpp +++ b/src/checks/inefficientqlistbase.cpp @@ -1,117 +1,117 @@ /* This file is part of the clazy static checker. Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Author: Sérgio Martins Copyright (C) 2015 Sergio Martins This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "inefficientqlistbase.h" #include "Utils.h" #include "TypeUtils.h" #include "ContextUtils.h" #include "TemplateUtils.h" #include "StmtBodyRange.h" #include "SourceCompatibilityHelpers.h" #include "StringUtils.h" #include #include #include #include #include #include #include #include #include class ClazyContext; namespace clang { class Stmt; } // namespace clang using namespace clang; using namespace std; InefficientQListBase::InefficientQListBase(const std::string &name, ClazyContext *context, int ignoreMode) : CheckBase(name, context) , m_ignoreMode(ignoreMode) { } bool InefficientQListBase::shouldIgnoreVariable(VarDecl *varDecl) const { DeclContext *context = varDecl->getDeclContext(); FunctionDecl *fDecl = context ? dyn_cast(context) : nullptr; if ((m_ignoreMode & IgnoreNonLocalVariable) && !clazy::isValueDeclInFunctionContext(varDecl)) { return true; } if ((m_ignoreMode & IgnoreInFunctionWithSameReturnType) && fDecl && fDecl->getReturnType().getCanonicalType() == varDecl->getType().getCanonicalType()) { return true; } Stmt *body = fDecl ? fDecl->getBody() : nullptr; if ((m_ignoreMode & IgnoreIsAssignedToInFunction) && Utils::isAssignedTo(body, varDecl)) { return true; } if ((m_ignoreMode & IgnoreIsPassedToFunctions) && Utils::isPassedToFunction(StmtBodyRange(body), varDecl, /*by-ref=*/ false)) { return true; } if ((m_ignoreMode & IgnoreIsInitializedByFunctionCall) && Utils::isInitializedExternally(varDecl)) { return true; } return false; } void InefficientQListBase::VisitDecl(clang::Decl *decl) { - VarDecl *varDecl = dyn_cast(decl); + auto varDecl = dyn_cast(decl); if (!varDecl) return; QualType type = varDecl->getType(); const Type *t = type.getTypePtrOrNull(); if (!t) return; CXXRecordDecl *recordDecl = t->getAsCXXRecordDecl(); - if (!recordDecl || clazy::name(recordDecl) != "QList") + if (!recordDecl || clazy::name(recordDecl) != "QList" || type.getAsString() == "QVariantList") return; const std::vector types = clazy::getTemplateArgumentsTypes(recordDecl); if (types.empty()) return; QualType qt2 = types[0]; if (!qt2.getTypePtrOrNull() || qt2->isIncompleteType()) return; const int size_of_ptr = TypeUtils::sizeOfPointer(&m_astContext, qt2); // in bits const int size_of_T = m_astContext.getTypeSize(qt2); if (size_of_T > size_of_ptr && !shouldIgnoreVariable(varDecl)) { string s = string("Use QVector instead of QList for type with size " + to_string(size_of_T / 8) + " bytes"); emitWarning(clazy::getLocStart(decl), s.c_str()); } } diff --git a/tests/inefficient-qlist/main.cpp b/tests/inefficient-qlist/main.cpp index a451f0e..ab6ba55 100644 --- a/tests/inefficient-qlist/main.cpp +++ b/tests/inefficient-qlist/main.cpp @@ -1,49 +1,55 @@ #include - +#include struct SmallType { char a[sizeof(void*)]; }; struct BigType { char a[9]; }; void foo() { QList bigT; // Warning QList smallT; // OK } class A { public: void foo() { m_big.clear(); } QList m_big; // Warning }; void foo1(QList big2) { QList bigt; // Warning bigt = big2; } void test_bug358740() { QList list; // OK int a, b; } + +void testQVariantList() +{ + QList list1; // Warn + QVariantList list2; // OK, to interact with Qt api probably +} diff --git a/tests/inefficient-qlist/main.cpp.expected b/tests/inefficient-qlist/main.cpp.expected index d6daa1d..8d9ad80 100644 --- a/tests/inefficient-qlist/main.cpp.expected +++ b/tests/inefficient-qlist/main.cpp.expected @@ -1,3 +1,4 @@ inefficient-qlist/main.cpp:24:5: warning: Use QVector instead of QList for type with size 9 bytes [-Wclazy-inefficient-qlist] inefficient-qlist/main.cpp:38:11: warning: Use QVector instead of QList for type with size 9 bytes [-Wclazy-inefficient-qlist] inefficient-qlist/main.cpp:40:5: warning: Use QVector instead of QList for type with size 9 bytes [-Wclazy-inefficient-qlist] +inefficient-qlist/main.cpp:53:5: warning: Use QVector instead of QList for type with size 16 bytes [-Wclazy-inefficient-qlist]