2010-10-12 19:54:39 +02:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2021-03-21 20:58:32 +01:00
|
|
|
* Copyright (C) 2007-2021 Cppcheck team.
|
2010-10-12 19:54:39 +02:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
2010-10-14 19:59:10 +02:00
|
|
|
// You should use ++ and -- as prefix whenever possible as these are more
|
2010-10-12 19:54:39 +02:00
|
|
|
// efficient than postfix operators
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "checkpostfixoperator.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
|
2022-01-27 19:03:20 +01:00
|
|
|
#include "errortypes.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "settings.h"
|
2011-07-23 21:14:15 +02:00
|
|
|
#include "symboldatabase.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "token.h"
|
|
|
|
|
2022-01-27 19:03:20 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2010-10-12 19:54:39 +02:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// Register this check class (by creating a static instance of it)
|
2011-10-13 20:53:06 +02:00
|
|
|
namespace {
|
|
|
|
CheckPostfixOperator instance;
|
2010-10-12 19:54:39 +02:00
|
|
|
}
|
|
|
|
|
CWE mapping of useAutoPointerMalloc, uselessCallsCompare, uselessCallsSwap, uselessCallsSubstr, uselessCallsEmpty, uselessCallsRemove, derefInvalidIterator, reademptycontainer, multiplySizeof, divideSizeof, stringLiteralWrite, incorrectStringCompare, literalWithCharPtrCompare, charLiteralWithCharPtrCompare, incorrectStringBooleanError, staticStringCompare, stringCompare, signConversion, truncLongCastAssignment, truncLongCastReturn, unusedFunction, unusedVariable, unusedAllocatedMemory, unreadVariable, unassignedVariable, unusedStructMember, postfixOperator, va_start_wrongParameter (#824)
Add an optional extended description…
2016-09-03 00:31:35 +02:00
|
|
|
|
|
|
|
// CWE ids used
|
|
|
|
static const struct CWE CWE398(398U); // Indicator of Poor Code Quality
|
|
|
|
|
|
|
|
|
2010-10-12 19:54:39 +02:00
|
|
|
void CheckPostfixOperator::postfixOperator()
|
|
|
|
{
|
2021-02-24 22:00:06 +01:00
|
|
|
if (!mSettings->severity.isEnabled(Severity::performance))
|
2010-10-12 19:54:39 +02:00
|
|
|
return;
|
|
|
|
|
2018-06-16 16:10:28 +02:00
|
|
|
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
|
2010-11-04 17:54:04 +01:00
|
|
|
|
2018-07-13 16:50:12 +02:00
|
|
|
for (const Scope * scope : symbolDatabase->functionScopes) {
|
2018-04-27 22:36:30 +02:00
|
|
|
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
|
2013-03-31 13:17:23 +02:00
|
|
|
const Variable *var = tok->variable();
|
2014-05-18 12:52:15 +02:00
|
|
|
if (!var || !Token::Match(tok, "%var% ++|--"))
|
|
|
|
continue;
|
2010-10-12 19:54:39 +02:00
|
|
|
|
2014-05-18 12:52:15 +02:00
|
|
|
const Token* parent = tok->next()->astParent();
|
|
|
|
if (!parent || parent->str() == ";" || (parent->str() == "," && (!parent->astParent() || parent->astParent()->str() != "("))) {
|
2013-03-31 13:17:23 +02:00
|
|
|
if (var->isPointer() || var->isArray())
|
|
|
|
continue;
|
2010-12-30 14:27:05 +01:00
|
|
|
|
2014-05-18 12:52:15 +02:00
|
|
|
if (Token::Match(var->nameToken()->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
|
2013-03-31 13:17:23 +02:00
|
|
|
// the variable is an iterator
|
|
|
|
postfixOperatorError(tok);
|
|
|
|
} else if (var->type()) {
|
|
|
|
// the variable is an instance of class
|
|
|
|
postfixOperatorError(tok);
|
2012-11-12 06:16:38 +01:00
|
|
|
}
|
2010-10-12 19:54:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
void CheckPostfixOperator::postfixOperatorError(const Token *tok)
|
|
|
|
{
|
2010-11-27 09:30:57 +01:00
|
|
|
reportError(tok, Severity::performance, "postfixOperator",
|
2010-11-27 19:54:02 +01:00
|
|
|
"Prefer prefix ++/-- operators for non-primitive types.\n"
|
2011-02-04 10:10:24 +01:00
|
|
|
"Prefix ++/-- operators should be preferred for non-primitive types. "
|
2010-11-27 09:30:57 +01:00
|
|
|
"Pre-increment/decrement can be more efficient than "
|
|
|
|
"post-increment/decrement. Post-increment/decrement usually "
|
|
|
|
"involves keeping a copy of the previous value around and "
|
2021-02-24 22:00:06 +01:00
|
|
|
"adds a little extra code.", CWE398, Certainty::normal);
|
2010-10-12 19:54:39 +02:00
|
|
|
}
|