Added rule to simplify token matching
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
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.
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.
We might also change tok->next()->link() to tok->linkAt(1) while we are at it.
tok->next()->link()totok->linkAt(1)while we are at it.
Good idea, added this rule in accordance.
We might also change
tok->next()->link()totok->linkAt(1)while we are at it.
This rule provides a bunch of results. I'll provide a seperate PR (https://github.com/danmar/cppcheck/pull/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(), ")|} ;")) { ^
`
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.
Aren't these rules in the selfcheck already?
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.
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.
Aren't these rules in the selfcheck already?
No, that file is unused. As mentioned in my previous comment we have the
internalcheck 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.
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).
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.
IIRC @pfultz2 is/was using rule files at some point.
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?
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.
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.
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.
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.
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.
#6211 at least tries to encapsulate it so it could be replaced with something else.
:+1:
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.
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.
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++.
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).
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.
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. :-(
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.