Skip to content

Added rule to simplify token matching #6472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

orbitcowboy
Copy link
Collaborator

This rule catches cases where multiple tok->next()-next() calls can be simplified to tok-tokAt(2)

Reference: https://github.com/danmar/cppcheck/pull/6442/files/13b2cabb6384ff5279b17a75062a63c5f240f74a#r1623220527

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

We should integrate this into the selfcheck.

And we should also evaluate if parts of the internal check could be implemented using rules instead.

A Python test for this file so it works as expected would also be great.

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

Applying these changes might incur a minor performance hit as it performs additional checks. Also the code is probably not being inlined as the implementation is inside the source.

@chrchr-github
Copy link
Collaborator

We might also change tok->next()->link() to tok->linkAt(1) while we are at it.

@orbitcowboy
Copy link
Collaborator Author

tok->next()->link() to tok->linkAt(1) while we are at it.

Good idea, added this rule in accordance.

@orbitcowboy
Copy link
Collaborator Author

orbitcowboy commented Jun 1, 2024

We might also change tok->next()->link() to tok->linkAt(1) while we are at it.

This rule provides a bunch of results. I'll provide a seperate PR (#6476) to fix them. The interesting part, is if performance is affected by these changes. In general, it makes the code more readable.

These are the findings
`
lib/checkboost.cpp:43:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token containerTok = tok->next()->link()->previous();
^
lib/checkassert.cpp:58:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token endTok = tok->next()->link();
^
lib/checkexceptionsafety.cpp:66:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/checkexceptionsafety.cpp:71:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link(); // end of if ( ... )
^
lib/checkexceptionsafety.cpp:72:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link(); // end of { ... }
^
lib/checkexceptionsafety.cpp:186:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::simpleMatch(tok, "catch (") && tok->next()->link() && tok->next()->link()->next()) { // Don't check inner catch - it is handled in another iteration of outer loop.
^
lib/checkexceptionsafety.cpp:187:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->next()->link();
^
lib/checkbufferoverrun.cpp:790:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token tok2 = tok->next()->link(); tok2 != scope->bodyEnd; tok2 = tok2->next()) {
^
lib/checkmemoryleak.cpp:863:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok3 = tok3->next()->link();
^
lib/checkmemoryleak.cpp:870:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok3 = tok3->next()->link();
^
lib/checkmemoryleak.cpp:876:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok3 = tok3->next()->link();
^
lib/checkmemoryleak.cpp:1106:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token endParamToken = tok->next()->link();
^
lib/checkmemoryleak.cpp:1115:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok2, "shared_ptr|unique_ptr <") && Token::Match(tok2->next()->link(), "> ( new %name%")) {
^
lib/checkmemoryleak.cpp:1120:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
else if (tok2->isName() && Token::simpleMatch(tok2->next()->link(), "> ("))
^
lib/checkmemoryleak.cpp:1129:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token
tok2 = functionCalled->tokAt(2); tok2 != functionCalled->next()->link(); tok2 = tok2->next())
^
lib/checkmemoryleak.cpp:1134:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token
tok2 = pointerType->tokAt(2); tok2 != pointerType->next()->link(); tok2 = tok2->next())
^
lib/checknullpointer.cpp:288:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/checknullpointer.cpp:350:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/checknullpointer.cpp:358:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
else if (Token::Match(tok, "0 [") && (tok->previous()->str() != "&" || !Token::Match(tok->next()->link()->next(), "[.(]")))
^
lib/checkstring.cpp:290:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
(Token::Match(tok->tokAt(2), "%str% &&") || Token::Match(tok->next()->link()->tokAt(-2), "&& %str% )")))
^
lib/checkstring.cpp:291:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/checkleakautovar.cpp:704:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = ftok->next()->link();
^
lib/checkcondition.cpp:194:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!islocal && Token::Match(tok2, "%name% (") && !Token::simpleMatch(tok2->next()->link(), ") {"))
^
lib/checkcondition.cpp:208:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token * const end = tok2->next()->link();
^
lib/checkcondition.cpp:230:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::simpleMatch(end->next()->link(), "} else {"))
^
lib/checkcondition.cpp:231:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
ret2 = assignIfParseScope(assignTok, end->next()->link()->tokAt(3), varid, islocal, bitop, num);
^
lib/checkcondition.cpp:1806:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!Token::simpleMatch(tok->next()->link(), ") {"))
^
lib/checkcondition.cpp:1808:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token blockTok = tok->next()->link()->next();
^
lib/checkclass.cpp:952:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token tok2 = ftok->next()->link(); tok2 && tok2 != ftok; tok2 = tok2->previous()) {
^
lib/checkclass.cpp:1023:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token tok = ftok->tokAt(2); tok && tok != ftok->next()->link(); tok = tok->next()) {
^
lib/checkclass.cpp:1050:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/checkclass.cpp:2410:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (const Token
tok = lpar->next(); tok && tok != funcTok->next()->link(); tok = tok->next()) {
^
lib/checkuninitvar.cpp:506:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->next();
^
lib/checkuninitvar.cpp:586:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token end = tok->next()->link();
^
lib/checkuninitvar.cpp:633:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token tok2 = forwhile ? tok->next()->link()->next() : tok->next();
^
lib/checkuninitvar.cpp:645:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token startCond = forwhile ? tok->next() : tok->next()->link()->tokAt(2);
^
lib/findtoken.h:94:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok, "if|for|while (") && Token::simpleMatch(tok->next()->link(), ") {")) {
^
lib/astutils.cpp:487:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok, "%name% <") && Token::simpleMatch(tok->next()->link(), "> ("))
^
lib/astutils.cpp:541:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
while (Token::Match(rightmostLeaf->next(), "]|)") && !hasToken(rightmostLeaf->next()->link(), rightmostLeaf->next(), tok))
^
lib/astutils.cpp:1697:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if ((tok1->next() && tok1->next()->link() && Token::Match(tok1, "%name% <")) ||
^
lib/astutils.cpp:1698:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
(tok2->next() && tok2->next()->link() && Token::Match(tok2, "%name% <"))) {
^
lib/astutils.cpp:1701:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (pure && Token::simpleMatch(tok1->next()->link(), "> (") &&
^
lib/checkother.cpp:3218:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
condEnd = tok->next()->link();
^
lib/checkother.cpp:3221:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (condEnd && condEnd->next() && condEnd->next()->link()) {
^
lib/checkother.cpp:3222:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
ifEndTok = condEnd->next()->link();
^
lib/checkunusedvar.cpp:1072:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::Match(tok->next()->link(), ") %var% [,)[]")) {
^
lib/checkunusedvar.cpp:1073:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
variables.use(tok->next()->link()->next()->varId(), tok); // use = read + write
^
lib/forwardanalyzer.cpp:659:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::simpleMatch(tok->next()->link(), ") {")) {
^
lib/forwardanalyzer.cpp:665:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
endCond = tok->next()->link();
^
lib/forwardanalyzer.cpp:666:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
endBlock = endCond->next()->link();
^
lib/forwardanalyzer.cpp:772:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
endBlock = tok->next()->link();
^
lib/forwardanalyzer.cpp:795:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
endBlock = tok->next()->link();
^
lib/pathanalysis.cpp:126:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
} else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) {
^
lib/pathanalysis.cpp:127:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token * endCond = tok->next()->link();
^
lib/pathanalysis.cpp:128:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token * endBlock = endCond->next()->link();
^
lib/pathanalysis.cpp:133:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (forwardRange(tok->next(), tok->next()->link(), info, f) == Progress::Break)
^
lib/checkstl.cpp:1113:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
blockStart = tok->next()->link()->next();
^
lib/checkstl.cpp:1691:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!Token::simpleMatch(tok->next()->link(), ") {"))
^
lib/checkstl.cpp:1705:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token *thenTok = tok->next()->link()->next();
^
lib/checkstl.cpp:2043:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok->next()->link();
^
lib/checkstl.cpp:2423:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/checkstl.cpp:2745:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
: bodyTok(tok->next()->link()->next()), settings(psettings)
^
lib/checkstl.cpp:2896:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!Token::simpleMatch(tok->next()->link(), ") {"))
^
lib/checkstl.cpp:2905:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token bodyTok = tok->next()->link()->next();
^
lib/checkstl.cpp:3117:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!Token::simpleMatch(tok->next()->link(), ") {"))
^
lib/tokenlist.cpp:807:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->next();
^
lib/tokenlist.cpp:1600:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token * const endPar = tok->next()->link();
^
lib/templatesimplifier.cpp:299:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/templatesimplifier.cpp:303:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/templatesimplifier.cpp:2806:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
eraseTokens(tok, tok->next()->link());
^
lib/templatesimplifier.cpp:2815:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
eraseTokens(tok, tok->next()->link());
^
lib/templatesimplifier.cpp:2827:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
eraseTokens(tok, tok->next()->link());
^
lib/templatesimplifier.cpp:2836:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
eraseTokens(tok, tok->next()->link());
^
lib/valueflow.cpp:586:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
rhstok = tok->next()->link()->tokAt(2);
^
lib/valueflow.cpp:607:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token *rhstok = vartok->next()->link()->tokAt(2);
^
lib/valueflow.cpp:615:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token strtok = vartok->next()->link()->tokAt(2);
^
lib/valueflow.cpp:4194:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
else if (Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->next()->link(), ") {")) {
^
lib/valueflow.cpp:6347:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/valueflow.cpp:7968:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
!(Token::Match(nameToken, "%name% {") && Token::simpleMatch(nameToken->next()->link(), "} ;")) &&
^
lib/tokenize.cpp:7789:0: error: Simplify 'tok->next()->next()' to 'tok->tokAt(2).' [TokenNext]
Token::createMutualLinks(semicolon->next()->next(), endpar);
^
lib/tokenize.cpp:285:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tokPtr = end->next()->link();
^
lib/tokenize.cpp:515:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:536:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:541:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:546:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:1471:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tokOffset->next() && Token::Match(tokOffset->next()->link()->previous(), "%type% ) (") &&
^
lib/tokenize.cpp:1472:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::Match(tokOffset->next()->link()->next()->link(), ") const|volatile| ) ;|,")) ||
^
lib/tokenize.cpp:1492:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
argEnd = tokOffset->next()->link();
^
lib/tokenize.cpp:2187:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:2191:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link();
^
lib/tokenize.cpp:2314:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2 = tok2->next()->link()->next();
^
lib/tokenize.cpp:3721:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
} else if (Token::simpleMatch(tok, "{ {") && Token::simpleMatch(tok->next()->link(), "} }")) {
^
lib/tokenize.cpp:3723:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok->next()->link()->deleteThis();
^
lib/tokenize.cpp:5248:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (tok3 && tok3->next() && tok3->next()->link())
^
lib/tokenize.cpp:5249:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok3 = tok3->next()->link();
^
lib/tokenize.cpp:5254:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, mVarId);
^
lib/tokenize.cpp:5557:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:6904:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:6937:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:7072:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:7079:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (!tok->next()->link())
^
lib/tokenize.cpp:7091:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
for (Token
tok2 = tok->next(); tok2 != tok->next()->link(); tok2 = tok2->next()) {
^
lib/tokenize.cpp:7098:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:7102:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/tokenize.cpp:7846:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok->link() && tok->link()->previous() == tok->next()->link()) {
^
lib/tokenize.cpp:8005:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token * end = tok->next()->link();
^
lib/tokenize.cpp:8266:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
return Token::simpleMatch(tok, "alignas (") && tok->next()->link();
^
lib/tokenize.cpp:8275:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
return tok->next()->link();
^
lib/tokenize.cpp:8602:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->previous(); // find ")" of the for-loop
^
lib/tokenize.cpp:8936:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok->next()->link(), "} const| |&| const| %type% ,|;|[|(|{|=")) {
^
lib/tokenize.cpp:8951:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
start->next()->link()->deleteThis();
^
lib/tokenize.cpp:9147:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok->next()->link()->insertToken("__property");
^
lib/tokenize.cpp:9149:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::eraseTokens(tok, tok->next()->link()->next());
^
lib/tokenize.cpp:9570:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok->next()->link()->next()) {
^
lib/tokenize.cpp:9571:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
instruction = tok->tokAt(2)->stringifyList(tok->next()->link());
^
lib/tokenize.cpp:9572:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::eraseTokens(tok, tok->next()->link()->next());
^
lib/tokenize.cpp:9665:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token last = tok->next()->link();
^
lib/tokenize.cpp:9780:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::eraseTokens(tok1, tok1->next()->link());
^
lib/tokenize.cpp:9907:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::move(tok1->previous(), tok2->tokAt(-2), tok->next()->link()->previous()); // Swap third with second argument
^
lib/tokenize.cpp:10087:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->next();
^
lib/symboldatabase.cpp:214:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok2->next()->link()->strAt(1) == ";")
^
lib/symboldatabase.cpp:215:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok2->next()->link()->next();
^
lib/symboldatabase.cpp:426:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::Match(tok->next()->link(), "} |&| %name% ;|[|=")) {
^
lib/symboldatabase.cpp:432:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
varNameTok = tok->next()->link()->next();
^
lib/symboldatabase.cpp:467:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::simpleMatch(tok->next()->link(), "} ;")) ||
^
lib/symboldatabase.cpp:716:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
} else if (tok->isKeyword() && Token::Match(tok, "if|for|while|catch|switch (") && Token::simpleMatch(tok->next()->link(), ") {")) {
^
lib/symboldatabase.cpp:717:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token scopeStartTok = tok->next()->link()->next();
^
lib/symboldatabase.cpp:737:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
endInitList.emplace(tok->next()->link(), scope);
^
lib/symboldatabase.cpp:1156:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (tok->next()->str() == ">" && !tok->next()->link())
^
lib/symboldatabase.cpp:1351:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
(Token::Match(tok->next()->link(), ") . %name% !!(") ||
^
lib/symboldatabase.cpp:1352:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
(Token::Match(tok->next()->link(), ") [") && Token::Match(tok->next()->link()->next()->link(), "] . %name% !!(")))) {
^
lib/symboldatabase.cpp:1355:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (tok->next()->link()->next()->str() == ".")
^
lib/symboldatabase.cpp:1356:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
membertok = tok->next()->link()->next()->next();
^
lib/symboldatabase.cpp:1358:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
membertok = tok->next()->link()->next()->link()->next()->next();
^
lib/symboldatabase.cpp:1379:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
astIsContainer(tok->astParent()->astOperand1()) && Token::Match(tok->next()->link(), ") . %name% !!(")) {
^
lib/symboldatabase.cpp:1384:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token
memberTok = tok->next()->link()->tokAt(2);
^
lib/symboldatabase.cpp:1660:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok, "decltype|sizeof|typeof (") && tok->next()->link()) {
^
lib/symboldatabase.cpp:1661:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->previous();
^
lib/symboldatabase.cpp:1676:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
inConstExpr = tok->next()->link();
^
lib/symboldatabase.cpp:1727:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok, "%name% <") && tok->next()->link()) {
^
lib/symboldatabase.cpp:1926:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
else if (!tok->isName() || !tok->next() || !tok->next()->link())
^
lib/symboldatabase.cpp:1934:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
tok2 = tok->next()->link()->next();
^
lib/symboldatabase.cpp:2030:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
(tok2->isUpperCaseName() && Token::Match(tok2, "%name% (") && tok2->next()->link()->strAt(1) == "{") ||
^
lib/symboldatabase.cpp:2055:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
else if (Token::Match(tok, "%name% <") && Token::simpleMatch(tok->next()->link(), "> (")) {
^
lib/symboldatabase.cpp:2058:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
tok2 = tok->next()->link()->next()->link();
^
lib/symboldatabase.cpp:2476:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::simpleMatch(typeTok->next(), "<") && typeTok->next()->link()) // skip template arguments
^
lib/symboldatabase.cpp:2477:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
typeTok = typeTok->next()->link();
^
lib/symboldatabase.cpp:3302:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token *closeParen = tok->next()->link();
^
lib/symboldatabase.cpp:3375:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token closeParen = tok->next()->link();
^
lib/symboldatabase.cpp:4454:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link();
^
lib/symboldatabase.cpp:4818:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::Match(tok->next()->link(), "} %name% ;|[")) {
^
lib/symboldatabase.cpp:4819:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
tok = tok->next()->link()->tokAt(2);
^
lib/symboldatabase.cpp:4822:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
if (Token::simpleMatch(tok->next()->link(), "} ;")) {
^
lib/symboldatabase.cpp:5043:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
const Token
closeTok = localTypeTok->next()->link();
^
lib/symboldatabase.cpp:5079:0: error: Simplify 'tok->next()->link()' to 'tok->linkAt(1).' [TokenLink]
Token::Match(localVarTok->next()->link(), ")|} ;")) {
^

`

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

I would prefer if we would add the existing rules to the selfcheck so we have a baseline and enforcement and then add the new rules along with the fixes in one PR so we have that properly associated.

@chrchr-github
Copy link
Collaborator

Aren't these rules in the selfcheck already?

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

Aren't these rules in the selfcheck already?

No, that file is unused. As mentioned in my previous comment we have the internal check implemented in source which does similar things.

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

I would also like to profile the impact of the changes first. It should be miniscule but just to be sure. I am not sure if I still get around to it today.

@chrchr-github
Copy link
Collaborator

Aren't these rules in the selfcheck already?

No, that file is unused. As mentioned in my previous comment we have the internal check implemented in source which does similar things.

groan
Who uses the rule file then?

I would also like to profile the impact of the changes first. It should be miniscule but just to be sure. I am not sure if I still get around to it today.

We already have similar simplification rules in place anyway.

@firewave
Copy link
Collaborator

firewave commented Jun 1, 2024

Who uses the rule file then?

I assume rules is yet another dumping ground folder with random leftovers, examples and external submissions. I have not checked the history of it (yet).

chrchr-github pushed a commit that referenced this pull request Jun 1, 2024
@danmar
Copy link
Owner

danmar commented Jun 3, 2024

thanks.. my problem with this is that I don't like the rule files and would rather like to get rid of this old mistake. It's not hard to implement it with an addon instead.

@chrchr-github
Copy link
Collaborator

IIRC @pfultz2 is/was using rule files at some point.

@firewave
Copy link
Collaborator

firewave commented Jun 5, 2024

thanks.. my problem with this is that I don't like the rule files and would rather like to get rid of this old mistake. It's not hard to implement it with an addon instead.

Are you suggesting to drop the feature as a whole?

@danmar
Copy link
Owner

danmar commented Jun 9, 2024

Are you suggesting to drop the feature as a whole?

yes personally I would like to drop this feature. I believe it is deprecated since about 10-15 years.

@orbitcowboy
Copy link
Collaborator Author

Are you suggesting to drop the feature as a whole?

yes personally I would like to drop this feature. I believe it is deprecated since about 10-15 years.

There are cases where PCRE Rules are still helpful, for example to enforce some very simple rules, such as forbidding special keyword usage like goto.
Of course, these rules can always be implemented in addons as well, but as it turned out, addons are much slower because of Python is involved.

IMHO: There is no need to deprecate this feature, one simply has to know when it is better to either implement a PCRE Rule or an addon or even a Cppcheck.

@firewave
Copy link
Collaborator

Of course, these rules can always be implemented in addons as well, but as it turned out, addons are much slower because of Python is involved.

Performance should be better and can probably still be improved. If you have an example I can take a look.

@danmar
Copy link
Owner

danmar commented Jun 11, 2024

There are cases where PCRE Rules are still helpful, for example to enforce some very simple rules, such as forbidding special keyword usage like goto.

If we could at least get rid of that stupid PCRE dependency that would be a major step forward.

Of course, these rules can always be implemented in addons as well, but as it turned out, addons are much slower because of Python is involved.

I would expect that an addon that search for goto would be very fast.

And addons does not have to be written with Python although we don't have ready-made open source code to import the dumpdata in any other language. Compiled languages can be used.

@firewave
Copy link
Collaborator

If we could at least get rid of that stupid PCRE dependency that would be a major step forward.

#6211 at least tries to encapsulate it so it could be replaced with something else.

@danmar
Copy link
Owner

danmar commented Jun 11, 2024

#6211 at least tries to encapsulate it so it could be replaced with something else.

👍

I don't know the exact difference of PCRE and C++ regex but I would imagine that it's only different in some edge cases.
@pfultz2 @orbitcowboy do you have some opinions about dropping PCRE and using c++ regex instead? if so what are the features that you would miss.

Getting rid of PCRE dependency would be a big relief.

@firewave
Copy link
Collaborator

I don't know the exact difference of PCRE and C++ regex but I would imagine that it's only different in some edge cases.

PCRE is super fast and std::regex is probably the slowest implementation in history so it is basically unusable.

@pfultz2
Copy link
Contributor

pfultz2 commented Jun 11, 2024

PCRE is super fast and std::regex is probably the slowest implementation in history so it is basically unusable.

Yes std::regex is really slow, and wont be fixed since it will break ABI at least in libstdc++.

@pfultz2
Copy link
Contributor

pfultz2 commented Jun 11, 2024

There are cases where PCRE Rules are still helpful, for example to enforce some very simple rules, such as forbidding special keyword usage like goto.

Its really easy to write an addon for such a check(and this is the entire python file):

@cppcheck.checker
def GotoStatement(cfg, data):
    for token in cfg.tokenlist:
        if token.str != 'goto':
            continue
        cppcheck.reportError(token, "style", "Goto considered harmful.")

Where I still use the rules, its actually for cases where I have a more complicated regex(such as for \( (?:(?:\w+|<|>|::) )*(?:\w+|>)(?: &|\*)* (\w+) : (?:[^()]*(\([^()]*(?-1)*[^()]*\)))*[^)]*\) { (?:(?<idx1>\w+) \+\+|\+\+ (?<idx2>\w+)) ; if (\([^()]*(?-1)*[^()]*\)) { \w+ = \g{idx1}|\g{idx2} ; (?:break ; )?(?:return [^;]*; )?} }]]>). It can definitely be converted to an addon but it is a lot more work, which is why I havent gotten around to do it.

Also, the PCRE rules run much faster than an addon(loading the xml in python is much slower than running a regex directly).

@danmar
Copy link
Owner

danmar commented Jun 12, 2024

PCRE is super fast and std::regex is probably the slowest implementation in history so it is basically unusable.

I would understand that argument if it was executed directly on the file.

I would assume that std::regex finish in a fraction of the time it takes for cppcheck to parse the file and to perform its valueflow.

@danmar
Copy link
Owner

danmar commented Jun 12, 2024

Where I still use the rules, its actually for cases where I have a more complicated regex(such as

that looks like a case that would benefit to be implemented in python instead :-) as the python script could be flexible. and I assume more readable.

I don't see what the regexp does actually. :-(

@firewave
Copy link
Collaborator

firewave commented Dec 3, 2024

Closing as the file in question has been removed in #6951. IIRC the internal check was also improved to detect this. If there is still something to be improved on, please file a ticket so it is tracked.

@firewave firewave closed this Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants