Skip to content

Commit 1a4e3dc

Browse files
author
Debrard Sebastien
committed
increment check
1 parent 9e15c4e commit 1a4e3dc

7 files changed

Lines changed: 541 additions & 146 deletions

File tree

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ LIBOBJ = lib/checkautovariables.o \
2828
lib/checkexceptionsafety.o \
2929
lib/checkmemoryleak.o \
3030
lib/checkobsoletefunctions.o \
31+
lib/checkpostfixoperator.o \
3132
lib/checkother.o \
3233
lib/checkstl.o \
3334
lib/checkunusedfunctions.o \
@@ -65,6 +66,7 @@ TESTOBJ = test/options.o \
6566
test/testmathlib.o \
6667
test/testmemleak.o \
6768
test/testobsoletefunctions.o \
69+
test/testpostfixoperator.o \
6870
test/testoptions.o \
6971
test/testother.o \
7072
test/testpreprocessor.o \
@@ -141,6 +143,9 @@ lib/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/checkmemoryleak.h lib/check.h
141143
lib/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h
142144
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkobsoletefunctions.o lib/checkobsoletefunctions.cpp
143145

146+
lib/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/checkpostfixoperator.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h
147+
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkpostfixoperator.o lib/checkpostfixoperator.cpp
148+
144149
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
145150
$(CXX) $(CXXFLAGS) -Ilib -c -o lib/checkother.o lib/checkother.cpp
146151

@@ -246,6 +251,9 @@ test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/checkmemoryleak.h li
246251
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
247252
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testobsoletefunctions.o test/testobsoletefunctions.cpp
248253

254+
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
255+
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testpostfixoperator.o test/testpostfixoperator.cpp
256+
249257
test/testoptions.o: test/testoptions.cpp test/options.h test/testsuite.h lib/errorlogger.h test/redirect.h
250258
$(CXX) $(CXXFLAGS) -Ilib -Icli -c -o test/testoptions.o test/testoptions.cpp
251259

lib/checkother.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3937,39 +3937,6 @@ void CheckOther::checkMisusedScopedObject()
39373937
}
39383938
}
39393939

3940-
3941-
void CheckOther::postIncrement()
3942-
{
3943-
if (!_settings->_checkCodingStyle || !_settings->inconclusive)
3944-
return;
3945-
3946-
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
3947-
{
3948-
if (Token::simpleMatch(tok, "for ("))
3949-
{
3950-
const Token *tok2 = tok->next()->link();
3951-
if (tok2)
3952-
tok2 = tok2->tokAt(-3);
3953-
if (Token::Match(tok2, "; %var% ++|-- )"))
3954-
{
3955-
if (tok2->next()->varId() == 0)
3956-
continue;
3957-
3958-
// Take a look at the variable declaration
3959-
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok2->tokAt(1)->varId());
3960-
const std::string classDef = std::string("class ") + std::string(decltok->previous()->strAt(0));
3961-
3962-
// Is the variable an iterator?
3963-
if (decltok && Token::Match(decltok->previous(), "iterator|const_iterator"))
3964-
postIncrementError(tok2, tok2->strAt(1), (std::string("++") == tok2->strAt(2)));
3965-
// Is the variable a class?
3966-
else if (Token::findmatch(_tokenizer->tokens(), classDef.c_str()))
3967-
postIncrementError(tok2, tok2->strAt(1), (std::string("++") == tok2->strAt(2)));
3968-
}
3969-
}
3970-
}
3971-
}
3972-
39733940
void CheckOther::cstyleCastError(const Token *tok)
39743941
{
39753942
reportError(tok, Severity::style, "cstyleCast", "C-style pointer casting");
@@ -4096,12 +4063,6 @@ void CheckOther::mathfunctionCallError(const Token *tok, const unsigned int numP
40964063
reportError(tok, Severity::error, "wrongmathcall", "Passing value " " to " "() leads to undefined result");
40974064
}
40984065

4099-
void CheckOther::postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement)
4100-
{
4101-
std::string type = (isIncrement ? "Incrementing" : "Decrementing");
4102-
reportError(tok, Severity::style, "postIncrementDecrement", ("Pre-" + type + " variable '" + var_name + "' is preferred to Post-" + type));
4103-
}
4104-
41054066
void CheckOther::emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty)
41064067
{
41074068
if (isTestForEmpty)

lib/checkother.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ class CheckOther : public Check
7575
checkOther.checkConstantFunctionParameter();
7676
checkOther.checkIncompleteStatement();
7777
checkOther.checkEmptyStringTest();
78-
checkOther.postIncrement();
7978

8079
checkOther.invalidFunctionUsage();
8180
checkOther.checkZeroDivision();
@@ -156,9 +155,6 @@ class CheckOther : public Check
156155
/** @brief %Check for parameters given to math function that do not make sense*/
157156
void checkMathFunctions();
158157

159-
/** @brief %Check for post increment/decrement in for loop*/
160-
void postIncrement();
161-
162158
void lookupVar(const Token *tok1, const std::string &varname);
163159

164160
/** @brief %Check for inefficient empty string test*/
@@ -212,7 +208,6 @@ class CheckOther : public Check
212208
void uninitvarError(const Token *tok, const std::string &varname);
213209
void zerodivError(const Token *tok);
214210
void mathfunctionCallError(const Token *tok, const unsigned int numParam = 1);
215-
void postIncrementError(const Token *tok, const std::string &var_name, const bool isIncrement);
216211
void emptyStringTestError(const Token *tok, const std::string &var_name, const bool isTestForEmpty);
217212
void fflushOnInputStreamError(const Token *tok, const std::string &varname);
218213
void redundantAssignmentInSwitchError(const Token *tok, const std::string &varname);
@@ -252,8 +247,6 @@ class CheckOther : public Check
252247
assignmentInAssertError(0, "varname");
253248
invalidScanfError(0);
254249

255-
// optimisations
256-
postIncrementError(0, "varname", true);
257250
emptyStringTestError(0, "varname", true);
258251
}
259252

lib/checkpostfixoperator.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
//---------------------------------------------------------------------------
20+
// You should use ++ and -- as prefix whenever possible as these are more
21+
// efficient than postfix operators
22+
//---------------------------------------------------------------------------
23+
24+
#include "checkpostfixoperator.h"
25+
#include <string>
26+
27+
//---------------------------------------------------------------------------
28+
29+
30+
// Register this check class (by creating a static instance of it)
31+
namespace
32+
{
33+
CheckPostfixOperator instance;
34+
}
35+
36+
void CheckPostfixOperator::postfixOperator()
37+
{
38+
if (!_settings->_checkCodingStyle)
39+
return;
40+
41+
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
42+
{
43+
bool result = false;
44+
if ( Token::Match(tok, "++|--") ) {
45+
if ( Token::Match(tok->previous()->previous(), ";|{|}") && Token::Match(tok->next(), ";|)|,") ) {
46+
result = true;
47+
}
48+
else if (tok->strAt(-2) == ",") {
49+
unsigned int i(1);
50+
while(tok->strAt(i) != ")") {
51+
if(tok->strAt(i) == ";") {
52+
result = true;
53+
break;
54+
}
55+
++i;
56+
}
57+
}
58+
else if (tok->strAt(-2) == "<<" && tok->strAt(1) == "<<") {
59+
result = true;
60+
}
61+
}
62+
63+
if(result) {
64+
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->previous()->varId());
65+
if (decltok && Token::Match(decltok->previous(), "iterator|const_iterator|reverse_iterator|const_reverse_iterator")) {
66+
// the variable an iterator
67+
postfixOperatorError(tok);
68+
}
69+
else {
70+
const std::string classDef = std::string("class ") + std::string(decltok->previous()->strAt(0));
71+
if (Token::findmatch(_tokenizer->tokens(), classDef.c_str())) {
72+
postfixOperatorError(tok);
73+
}
74+
}
75+
}
76+
}
77+
}
78+
//---------------------------------------------------------------------------
79+
80+
81+
void CheckPostfixOperator::postfixOperatorError(const Token *tok)
82+
{
83+
reportError(tok, Severity::style, "postfixOperator", "You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators");
84+
}

lib/checkpostfixoperator.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
20+
//---------------------------------------------------------------------------
21+
#ifndef CheckPostfixOperatorH
22+
#define CheckPostfixOperatorH
23+
//---------------------------------------------------------------------------
24+
25+
#include "check.h"
26+
27+
/// @addtogroup Checks
28+
/// @{
29+
30+
/**
31+
* @brief Using postfix operators ++ or -- rather than postfix operator.
32+
*/
33+
34+
class CheckPostfixOperator : public Check
35+
{
36+
public:
37+
/** This constructor is used when registering the CheckPostfixOperator */
38+
CheckPostfixOperator() : Check()
39+
{ }
40+
41+
/** This constructor is used when running checks. */
42+
CheckPostfixOperator(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
43+
: Check(tokenizer, settings, errorLogger)
44+
{ }
45+
46+
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
47+
{
48+
CheckPostfixOperator checkPostfixOperator(tokenizer, settings, errorLogger);
49+
checkPostfixOperator.postfixOperator();
50+
}
51+
52+
/** Check postfix operators */
53+
void postfixOperator();
54+
55+
private:
56+
/** Report Error */
57+
void postfixOperatorError(const Token *tok);
58+
59+
void getErrorMessages()
60+
{
61+
postfixOperatorError(0);
62+
}
63+
64+
std::string name() const
65+
{
66+
return "Using postfix operators";
67+
}
68+
69+
std::string classInfo() const
70+
{
71+
return "Warn if using postfix operators ++ or -- rather than prefix operator\n";
72+
}
73+
};
74+
/// @}
75+
//---------------------------------------------------------------------------
76+
#endif
77+

0 commit comments

Comments
 (0)