increment check
This commit is contained in:
parent
9e15c4ef38
commit
1a4e3dcc44
8
Makefile
8
Makefile
|
@ -28,6 +28,7 @@ LIBOBJ = lib/checkautovariables.o \
|
||||||
lib/checkexceptionsafety.o \
|
lib/checkexceptionsafety.o \
|
||||||
lib/checkmemoryleak.o \
|
lib/checkmemoryleak.o \
|
||||||
lib/checkobsoletefunctions.o \
|
lib/checkobsoletefunctions.o \
|
||||||
|
lib/checkpostfixoperator.o \
|
||||||
lib/checkother.o \
|
lib/checkother.o \
|
||||||
lib/checkstl.o \
|
lib/checkstl.o \
|
||||||
lib/checkunusedfunctions.o \
|
lib/checkunusedfunctions.o \
|
||||||
|
@ -65,6 +66,7 @@ TESTOBJ = test/options.o \
|
||||||
test/testmathlib.o \
|
test/testmathlib.o \
|
||||||
test/testmemleak.o \
|
test/testmemleak.o \
|
||||||
test/testobsoletefunctions.o \
|
test/testobsoletefunctions.o \
|
||||||
|
test/testpostfixoperator.o \
|
||||||
test/testoptions.o \
|
test/testoptions.o \
|
||||||
test/testother.o \
|
test/testother.o \
|
||||||
test/testpreprocessor.o \
|
test/testpreprocessor.o \
|
||||||
|
@ -141,6 +143,9 @@ lib/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/checkmemoryleak.h lib/check.h
|
||||||
lib/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h
|
lib/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h
|
||||||
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkobsoletefunctions.o lib/checkobsoletefunctions.cpp
|
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkobsoletefunctions.o lib/checkobsoletefunctions.cpp
|
||||||
|
|
||||||
|
lib/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/checkpostfixoperator.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h
|
||||||
|
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkpostfixoperator.o lib/checkpostfixoperator.cpp
|
||||||
|
|
||||||
lib/checkother.o: lib/checkother.cpp lib/checkother.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/mathlib.h lib/executionpath.h
|
lib/checkother.o: lib/checkother.cpp lib/checkother.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/mathlib.h lib/executionpath.h
|
||||||
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkother.o lib/checkother.cpp
|
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkother.o lib/checkother.cpp
|
||||||
|
|
||||||
|
@ -246,6 +251,9 @@ test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/checkmemoryleak.h li
|
||||||
test/testobsoletefunctions.o: test/testobsoletefunctions.cpp lib/tokenize.h lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h
|
test/testobsoletefunctions.o: test/testobsoletefunctions.cpp lib/tokenize.h lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h
|
||||||
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testobsoletefunctions.o test/testobsoletefunctions.cpp
|
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testobsoletefunctions.o test/testobsoletefunctions.cpp
|
||||||
|
|
||||||
|
test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/tokenize.h lib/checkpostfixoperator.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h
|
||||||
|
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testpostfixoperator.o test/testpostfixoperator.cpp
|
||||||
|
|
||||||
test/testoptions.o: test/testoptions.cpp test/options.h test/testsuite.h lib/errorlogger.h test/redirect.h
|
test/testoptions.o: test/testoptions.cpp test/options.h test/testsuite.h lib/errorlogger.h test/redirect.h
|
||||||
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testoptions.o test/testoptions.cpp
|
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testoptions.o test/testoptions.cpp
|
||||||
|
|
||||||
|
|
|
@ -3937,39 +3937,6 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckOther::postIncrement()
|
|
||||||
{
|
|
||||||
if (!_settings->_checkCodingStyle || !_settings->inconclusive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
|
||||||
{
|
|
||||||
if (Token::simpleMatch(tok, "for ("))
|
|
||||||
{
|
|
||||||
const Token *tok2 = tok->next()->link();
|
|
||||||
if (tok2)
|
|
||||||
tok2 = tok2->tokAt(-3);
|
|
||||||
if (Token::Match(tok2, "; %var% ++|-- )"))
|
|
||||||
{
|
|
||||||
if (tok2->next()->varId() == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Take a look at the variable declaration
|
|
||||||
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok2->tokAt(1)->varId());
|
|
||||||
const std::string classDef = std::string("class ") + std::string(decltok->previous()->strAt(0));
|
|
||||||
|
|
||||||
// Is the variable an iterator?
|
|
||||||
if (decltok && Token::Match(decltok->previous(), "iterator|const_iterator"))
|
|
||||||
postIncrementError(tok2, tok2->strAt(1), (std::string("++") == tok2->strAt(2)));
|
|
||||||
// Is the variable a class?
|
|
||||||
else if (Token::findmatch(_tokenizer->tokens(), classDef.c_str()))
|
|
||||||
postIncrementError(tok2, tok2->strAt(1), (std::string("++") == tok2->strAt(2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckOther::cstyleCastError(const Token *tok)
|
void CheckOther::cstyleCastError(const Token *tok)
|
||||||
{
|
{
|
||||||
reportError(tok, Severity::style, "cstyleCast", "C-style pointer casting");
|
reportError(tok, Severity::style, "cstyleCast", "C-style pointer casting");
|
||||||
|
@ -4096,12 +4063,6 @@ void CheckOther::mathfunctionCallError(const Token *tok, const unsigned int numP
|
||||||
reportError(tok, Severity::error, "wrongmathcall", "Passing value " " to " "() leads to undefined result");
|
reportError(tok, Severity::error, "wrongmathcall", "Passing value " " to " "() leads to undefined result");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement)
|
|
||||||
{
|
|
||||||
std::string type = (isIncrement ? "Incrementing" : "Decrementing");
|
|
||||||
reportError(tok, Severity::style, "postIncrementDecrement", ("Pre-" + type + " variable '" + var_name + "' is preferred to Post-" + type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckOther::emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty)
|
void CheckOther::emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty)
|
||||||
{
|
{
|
||||||
if (isTestForEmpty)
|
if (isTestForEmpty)
|
||||||
|
|
|
@ -75,7 +75,6 @@ public:
|
||||||
checkOther.checkConstantFunctionParameter();
|
checkOther.checkConstantFunctionParameter();
|
||||||
checkOther.checkIncompleteStatement();
|
checkOther.checkIncompleteStatement();
|
||||||
checkOther.checkEmptyStringTest();
|
checkOther.checkEmptyStringTest();
|
||||||
checkOther.postIncrement();
|
|
||||||
|
|
||||||
checkOther.invalidFunctionUsage();
|
checkOther.invalidFunctionUsage();
|
||||||
checkOther.checkZeroDivision();
|
checkOther.checkZeroDivision();
|
||||||
|
@ -156,9 +155,6 @@ public:
|
||||||
/** @brief %Check for parameters given to math function that do not make sense*/
|
/** @brief %Check for parameters given to math function that do not make sense*/
|
||||||
void checkMathFunctions();
|
void checkMathFunctions();
|
||||||
|
|
||||||
/** @brief %Check for post increment/decrement in for loop*/
|
|
||||||
void postIncrement();
|
|
||||||
|
|
||||||
void lookupVar(const Token *tok1, const std::string &varname);
|
void lookupVar(const Token *tok1, const std::string &varname);
|
||||||
|
|
||||||
/** @brief %Check for inefficient empty string test*/
|
/** @brief %Check for inefficient empty string test*/
|
||||||
|
@ -212,7 +208,6 @@ public:
|
||||||
void uninitvarError(const Token *tok, const std::string &varname);
|
void uninitvarError(const Token *tok, const std::string &varname);
|
||||||
void zerodivError(const Token *tok);
|
void zerodivError(const Token *tok);
|
||||||
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
|
||||||
void postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement);
|
|
||||||
void emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty);
|
void emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty);
|
||||||
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
|
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
|
||||||
void redundantAssignmentInSwitchError(const Token *tok, const std::string &varname);
|
void redundantAssignmentInSwitchError(const Token *tok, const std::string &varname);
|
||||||
|
@ -252,8 +247,6 @@ public:
|
||||||
assignmentInAssertError(0, "varname");
|
assignmentInAssertError(0, "varname");
|
||||||
invalidScanfError(0);
|
invalidScanfError(0);
|
||||||
|
|
||||||
// optimisations
|
|
||||||
postIncrementError(0, "varname", true);
|
|
||||||
emptyStringTestError(0, "varname", true);
|
emptyStringTestError(0, "varname", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// You should use ++ and -- as prefix whenever possible as these are more
|
||||||
|
// efficient than postfix operators
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "checkpostfixoperator.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Register this check class (by creating a static instance of it)
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
CheckPostfixOperator instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckPostfixOperator::postfixOperator()
|
||||||
|
{
|
||||||
|
if (!_settings->_checkCodingStyle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if ( Token::Match(tok, "++|--") ) {
|
||||||
|
if ( Token::Match(tok->previous()->previous(), ";|{|}") && Token::Match(tok->next(), ";|)|,") ) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else if (tok->strAt(-2) == ",") {
|
||||||
|
unsigned int i(1);
|
||||||
|
while(tok->strAt(i) != ")") {
|
||||||
|
if(tok->strAt(i) == ";") {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tok->strAt(-2) == "<<" && tok->strAt(1) == "<<") {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result) {
|
||||||
|
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->previous()->varId());
|
||||||
|
if (decltok && Token::Match(decltok->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
|
||||||
|
// the variable an iterator
|
||||||
|
postfixOperatorError(tok);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const std::string classDef = std::string("class ") + std::string(decltok->previous()->strAt(0));
|
||||||
|
if (Token::findmatch(_tokenizer->tokens(), classDef.c_str())) {
|
||||||
|
postfixOperatorError(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void CheckPostfixOperator::postfixOperatorError(const Token *tok)
|
||||||
|
{
|
||||||
|
reportError(tok, Severity::style, "postfixOperator", "You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators");
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#ifndef CheckPostfixOperatorH
|
||||||
|
#define CheckPostfixOperatorH
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "check.h"
|
||||||
|
|
||||||
|
/// @addtogroup Checks
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Using postfix operators ++ or -- rather than postfix operator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CheckPostfixOperator : public Check
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** This constructor is used when registering the CheckPostfixOperator */
|
||||||
|
CheckPostfixOperator() : Check()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/** This constructor is used when running checks. */
|
||||||
|
CheckPostfixOperator(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
|
: Check(tokenizer, settings, errorLogger)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
|
{
|
||||||
|
CheckPostfixOperator checkPostfixOperator(tokenizer, settings, errorLogger);
|
||||||
|
checkPostfixOperator.postfixOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check postfix operators */
|
||||||
|
void postfixOperator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Report Error */
|
||||||
|
void postfixOperatorError(const Token *tok);
|
||||||
|
|
||||||
|
void getErrorMessages()
|
||||||
|
{
|
||||||
|
postfixOperatorError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name() const
|
||||||
|
{
|
||||||
|
return "Using postfix operators";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string classInfo() const
|
||||||
|
{
|
||||||
|
return "Warn if using postfix operators ++ or -- rather than prefix operator\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/// @}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
#endif
|
||||||
|
|
|
@ -83,9 +83,6 @@ private:
|
||||||
|
|
||||||
TEST_CASE(oldStylePointerCast);
|
TEST_CASE(oldStylePointerCast);
|
||||||
|
|
||||||
TEST_CASE(postIncrementDecrementStl);
|
|
||||||
TEST_CASE(postIncrementDecrementClass);
|
|
||||||
|
|
||||||
TEST_CASE(dangerousStrolUsage);
|
TEST_CASE(dangerousStrolUsage);
|
||||||
|
|
||||||
TEST_CASE(passedByValue);
|
TEST_CASE(passedByValue);
|
||||||
|
@ -2380,103 +2377,6 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkpostIncrementDecrement(const char code[])
|
|
||||||
{
|
|
||||||
// Tokenize..
|
|
||||||
Tokenizer tokenizer;
|
|
||||||
std::istringstream istr(code);
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
|
||||||
tokenizer.setVarId();
|
|
||||||
|
|
||||||
// Clear the error buffer..
|
|
||||||
errout.str("");
|
|
||||||
|
|
||||||
// Check for redundant code..
|
|
||||||
Settings settings;
|
|
||||||
settings._checkCodingStyle = true;
|
|
||||||
settings.inconclusive = true;
|
|
||||||
CheckOther checkOther(&tokenizer, &settings, this);
|
|
||||||
checkOther.postIncrement();
|
|
||||||
}
|
|
||||||
|
|
||||||
void postIncrementDecrementStl()
|
|
||||||
{
|
|
||||||
checkpostIncrementDecrement("void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::list<int>::iterator it;\n"
|
|
||||||
" for (it = ab.begin(); it != ab.end(); it++)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Incrementing variable 'it' is preferred to Post-Incrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::list<int>::iterator it;\n"
|
|
||||||
" for (it = ab.begin(); it != ab.end(); it++)\n"
|
|
||||||
" ;\n"
|
|
||||||
" for (it = ab.begin(); it != ab.end(); it++)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Incrementing variable 'it' is preferred to Post-Incrementing\n"
|
|
||||||
"[test.cpp:6]: (style) Pre-Incrementing variable 'it' is preferred to Post-Incrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("void f2()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::list<int>::iterator it;\n"
|
|
||||||
" for (it = ab.end(); it != ab.begin(); it--)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Decrementing variable 'it' is preferred to Post-Decrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("void f2()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::list<int>::iterator it;\n"
|
|
||||||
" for (it = ab.end(); it != ab.begin(); it--)\n"
|
|
||||||
" ;\n"
|
|
||||||
" for (it = ab.end(); it != ab.begin(); it--)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Decrementing variable 'it' is preferred to Post-Decrementing\n"
|
|
||||||
"[test.cpp:6]: (style) Pre-Decrementing variable 'it' is preferred to Post-Decrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::list<std::vector<int> >::iterator it;\n"
|
|
||||||
" for (it = ab.begin(); it != ab.end(); it++)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Incrementing variable 'it' is preferred to Post-Incrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" std::map<int, std::vector<int> >::iterator it;\n"
|
|
||||||
" for (it = ab.begin(); it != ab.end(); it++)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Pre-Incrementing variable 'it' is preferred to Post-Incrementing\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void postIncrementDecrementClass()
|
|
||||||
{
|
|
||||||
checkpostIncrementDecrement("class TestClass;\n"
|
|
||||||
"void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" TestClass tClass;\n"
|
|
||||||
" for (tClass = TestClass.begin(); tClass != TestClass.end(); tClass++)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (style) Pre-Incrementing variable 'tClass' is preferred to Post-Incrementing\n", errout.str());
|
|
||||||
|
|
||||||
checkpostIncrementDecrement("class TestClass;\n"
|
|
||||||
"void f1()\n"
|
|
||||||
"{\n"
|
|
||||||
" TestClass tClass;\n"
|
|
||||||
" for (tClass = TestClass.end(); tClass != TestClass.begin(); tClass--)\n"
|
|
||||||
" ;\n"
|
|
||||||
"}\n");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (style) Pre-Decrementing variable 'tClass' is preferred to Post-Decrementing\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void dangerousStrolUsage()
|
void dangerousStrolUsage()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,372 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "tokenize.h"
|
||||||
|
#include "checkpostfixoperator.h"
|
||||||
|
#include "testsuite.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
extern std::ostringstream errout;
|
||||||
|
|
||||||
|
class TestPostfixOperator : public TestFixture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestPostfixOperator() : TestFixture("TestPostfixOperator")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void check(const char code[])
|
||||||
|
{
|
||||||
|
// Tokenize..
|
||||||
|
Tokenizer tokenizer;
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
tokenizer.simplifyTokenList();
|
||||||
|
|
||||||
|
// Assign variable ids
|
||||||
|
tokenizer.setVarId();
|
||||||
|
|
||||||
|
// Fill function list
|
||||||
|
tokenizer.fillFunctionList();
|
||||||
|
|
||||||
|
// Clear the error buffer..
|
||||||
|
errout.str("");
|
||||||
|
|
||||||
|
// Check for postfix operators..
|
||||||
|
Settings settings;
|
||||||
|
settings._checkCodingStyle = true;
|
||||||
|
settings.inconclusive = true;
|
||||||
|
CheckPostfixOperator checkPostfixOperator(&tokenizer, &settings, this);
|
||||||
|
checkPostfixOperator.postfixOperator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
TEST_CASE(testsimple);
|
||||||
|
TEST_CASE(testfor);
|
||||||
|
TEST_CASE(teststream);
|
||||||
|
TEST_CASE(testvolatile);
|
||||||
|
TEST_CASE(testiterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testsimple()
|
||||||
|
{
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" unsigned int k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" k++;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" if(k) {\n"
|
||||||
|
" k++;\n"
|
||||||
|
" }\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" k--;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" k++;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(1);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" if(k) {\n"
|
||||||
|
" k++;\n"
|
||||||
|
" }\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(1);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" if(k) {\n"
|
||||||
|
" ++k;\n"
|
||||||
|
" }\n"
|
||||||
|
" k++;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:10]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" k--;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" ++k;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" --k;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testfor()
|
||||||
|
{
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" for ( unsigned int i=0; i <= 10; i++) {\n"
|
||||||
|
" std::cout << i << std::endl;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" for ( K i(0); i <= 10; i++) {\n"
|
||||||
|
" std::cout << i << std::endl;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" for ( K i(0); i <= 10; ++i) {\n"
|
||||||
|
" std::cout << i << std::endl;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" for ( K i(10); i > 1; i--) {\n"
|
||||||
|
" std::cout << i << std::endl;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" for ( K i=10; i > 1; --i) {\n"
|
||||||
|
" std::cout << i << std::endl;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void teststream()
|
||||||
|
{
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" int k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" std::cout << k++ << std::endl;\n"
|
||||||
|
" std::cout << k-- << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" std::cout << k-- << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" std::cout << ++k << std::endl;\n"
|
||||||
|
" std::cout << --k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void testvolatile()
|
||||||
|
{
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"class K {};\n"
|
||||||
|
"int main(int argc, char *argv[])\n"
|
||||||
|
"{\n"
|
||||||
|
" volatile K k(0);\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" k++;\n"
|
||||||
|
" std::cout << k << std::endl;\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
TODO_ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void testiterator()
|
||||||
|
{
|
||||||
|
check("\n"
|
||||||
|
"#include <vector>\n"
|
||||||
|
"class Base {};\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" std::vector<Base*> v;\n"
|
||||||
|
" v.push_back(new Base());\n"
|
||||||
|
" v.push_back(new Base());\n"
|
||||||
|
" for (std::vector<Base*>::iterator i=v.begin(); i!=v.end(); i++) {\n"
|
||||||
|
" ;;\n"
|
||||||
|
" }\n"
|
||||||
|
" v.clear();\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"#include <vector>\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" std::vector<int> v;\n"
|
||||||
|
" std::vector<int>::iterator it;\n"
|
||||||
|
" for( int i=0; i < 10; ++i ) v.push_back(i);\n"
|
||||||
|
" unsigned int total = 0;\n"
|
||||||
|
" it = v.begin();\n"
|
||||||
|
" while( it != v.end() ) {\n"
|
||||||
|
" total += *it;\n"
|
||||||
|
" it++;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:12]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"#include <vector>\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" std::vector<int> v;\n"
|
||||||
|
" std::vector<int>::const_iterator it;\n"
|
||||||
|
" for( int i=0; i < 10; ++i ) v.push_back(i);\n"
|
||||||
|
" unsigned int total = 0;\n"
|
||||||
|
" it = v.begin();\n"
|
||||||
|
" while( it != v.end() ) {\n"
|
||||||
|
" it++;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:11]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
check("\n"
|
||||||
|
"#include <iostream>\n"
|
||||||
|
"#include <vector>\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" std::vector<int> v;\n"
|
||||||
|
" std::vector<int>::iterator it;\n"
|
||||||
|
" for( int i=0; i < 10; ++i ) v.push_back(i);\n"
|
||||||
|
" unsigned int total = 0;\n"
|
||||||
|
" std::vector<int>::reverse_iterator rit;\n"
|
||||||
|
" rit= v.rend();\n"
|
||||||
|
" while( rit != v.rbegin() ) {\n"
|
||||||
|
" rit--;\n"
|
||||||
|
" }\n"
|
||||||
|
" return 0;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:12]: (style) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators\n", errout.str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
REGISTER_TEST(TestPostfixOperator)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue