optimized non-matchcompiled Token::simpleMatch() a bit (#2640)

This commit is contained in:
Oliver Stöneberg 2020-05-26 20:13:56 +02:00 committed by GitHub
parent dc0b68d505
commit 4f68d85633
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 86 additions and 49 deletions

View File

@ -1428,7 +1428,7 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
continue;
std::string cast("( " + scope->className + " & )");
if (Token::simpleMatch(tok->next(), cast.c_str()))
if (Token::simpleMatch(tok->next(), cast.c_str(), cast.size()))
tok = tok->tokAt(4);
// check if a function is called
@ -1471,7 +1471,8 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
return;
}
if (startTok->next() == last) {
if (Token::simpleMatch(func->argDef, std::string("( const " + scope->className + " &").c_str())) {
const std::string tmp("( const " + scope->className + " &");
if (Token::simpleMatch(func->argDef, tmp.c_str(), tmp.size())) {
// Typical wrong way to suppress default assignment operator by declaring it and leaving empty
operatorEqMissingReturnStatementError(func->token, func->access == AccessControl::Public);
} else {
@ -1719,7 +1720,8 @@ void CheckClass::virtualDestructor()
if (Token::Match(tok, "[;{}] %var% =") &&
baseClassPointers.find(tok->next()->varId()) != baseClassPointers.end()) {
// new derived class..
if (Token::simpleMatch(tok->tokAt(3), ("new " + derivedClass->str()).c_str())) {
const std::string tmp("new " + derivedClass->str());
if (Token::simpleMatch(tok->tokAt(3), tmp.c_str(), tmp.size())) {
dontDelete.insert(tok->next()->varId());
}
}

View File

@ -2627,7 +2627,8 @@ void CheckOther::checkUnusedLabel()
tok = tok->scope()->bodyEnd;
if (Token::Match(tok, "{|}|; %name% :") && tok->strAt(1) != "default") {
if (!Token::findsimplematch(scope->bodyStart->next(), ("goto " + tok->strAt(1)).c_str(), scope->bodyEnd->previous()))
const std::string tmp("goto " + tok->strAt(1));
if (!Token::findsimplematch(scope->bodyStart->next(), tmp.c_str(), tmp.size(), scope->bodyEnd->previous()))
unusedLabelError(tok->next(), tok->next()->scope()->type == Scope::eSwitch);
}
}

View File

@ -1405,9 +1405,11 @@ void CheckUnusedVar::checkStructMemberUsage()
continue;
// Check if the struct member variable is used anywhere in the file
if (Token::findsimplematch(mTokenizer->tokens(), (". " + var.name()).c_str()))
std::string tmp(". " + var.name());
if (Token::findsimplematch(mTokenizer->tokens(), tmp.c_str(), tmp.size()))
continue;
if (Token::findsimplematch(mTokenizer->tokens(), (":: " + var.name()).c_str()))
tmp = (":: " + var.name());
if (Token::findsimplematch(mTokenizer->tokens(), tmp.c_str(), tmp.size()))
continue;
unusedStructMemberError(var.nameToken(), scope.className, var.name(), scope.type == Scope::eUnion);

View File

@ -2356,7 +2356,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
else if (arg_path_length && Token::Match(first->next(), "%name%") && first->strAt(1) != "const") {
std::string param = path;
if (Token::simpleMatch(second->next(), param.c_str())) {
if (Token::simpleMatch(second->next(), param.c_str(), param.size())) {
second = second->tokAt(int(arg_path_length));
arg_path_length = 0;
}
@ -2400,7 +2400,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
}
param = short_path;
if (Token::simpleMatch(second->next(), param.c_str())) {
if (Token::simpleMatch(second->next(), param.c_str(), param.size())) {
second = second->tokAt(int(short_path_length));
arg_path_length = 0;
}

View File

@ -1535,7 +1535,7 @@ bool TemplateSimplifier::alreadyHasNamespace(const TokenAndName &templateDeclara
pos += 2;
}
return Token::simpleMatch(tok->tokAt(offset), scope.c_str()) ;
return Token::simpleMatch(tok->tokAt(offset), scope.c_str(), scope.size());
}
void TemplateSimplifier::expandTemplate(
@ -1714,7 +1714,7 @@ void TemplateSimplifier::expandTemplate(
}
// check if type is instantiated
for (const auto & inst : mTemplateInstantiations) {
if (Token::simpleMatch(inst.token(), name.c_str())) {
if (Token::simpleMatch(inst.token(), name.c_str(), name.size())) {
// use the instantiated name
dst->insertToken(name, "", true);
start = closing;

View File

@ -560,14 +560,15 @@ int Token::multiCompare(const Token *tok, const char *haystack, nonneg int varid
return -1;
}
bool Token::simpleMatch(const Token *tok, const char pattern[])
bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_len)
{
if (!tok)
return false; // shortcut
const char *current = pattern;
const char *next = std::strchr(pattern, ' ');
const char *current = pattern;
const char *end = pattern + pattern_len;
const char *next = (const char*)std::memchr(pattern, ' ', pattern_len);
if (!next)
next = pattern + std::strlen(pattern);
next = end;
while (*current) {
const std::size_t length = next - current;
@ -579,7 +580,7 @@ bool Token::simpleMatch(const Token *tok, const char pattern[])
if (*next) {
next = std::strchr(++current, ' ');
if (!next)
next = current + std::strlen(current);
next = end;
}
tok = tok->next();
}
@ -938,19 +939,19 @@ Token * Token::findOpeningBracket()
//---------------------------------------------------------------------------
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[])
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
{
for (const Token* tok = startTok; tok; tok = tok->next()) {
if (Token::simpleMatch(tok, pattern))
if (Token::simpleMatch(tok, pattern, pattern_len))
return tok;
}
return nullptr;
}
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], const Token * const end)
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
{
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::simpleMatch(tok, pattern))
if (Token::simpleMatch(tok, pattern, pattern_len))
return tok;
}
return nullptr;

View File

@ -262,7 +262,12 @@ public:
* @return true if given token matches with given pattern
* false if given token does not match with given pattern
*/
static bool simpleMatch(const Token *tok, const char pattern[]);
template<size_t count>
static bool simpleMatch(const Token *tok, const char (&pattern)[count]) {
return simpleMatch(tok, pattern, count-1);
}
static bool simpleMatch(const Token *tok, const char pattern[], size_t pattern_len);
/**
* Match given token (or list of tokens) to a pattern list.
@ -669,16 +674,36 @@ public:
setFlag(fIsTemplateArg, value);
}
static const Token *findsimplematch(const Token * const startTok, const char pattern[]);
static const Token *findsimplematch(const Token * const startTok, const char pattern[], const Token * const end);
template<size_t count>
static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count]) {
return findsimplematch(startTok, pattern, count-1);
}
static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len);
template<size_t count>
static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count], const Token * const end) {
return findsimplematch(startTok, pattern, count-1, end);
}
static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end);
static const Token *findmatch(const Token * const startTok, const char pattern[], const nonneg int varId = 0);
static const Token *findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);
static Token *findsimplematch(Token * const startTok, const char pattern[]) {
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern));
template<size_t count>
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count]) {
return findsimplematch(startTok, pattern, count-1);
}
static Token *findsimplematch(Token * const startTok, const char pattern[], const Token * const end) {
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, end));
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len) {
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len));
}
template<size_t count>
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count], const Token * const end) {
return findsimplematch(startTok, pattern, count-1, end);
}
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end) {
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len, end));
}
static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0) {
return const_cast<Token *>(findmatch(const_cast<const Token *>(startTok), pattern, varId));
}

View File

@ -1120,7 +1120,7 @@ void Tokenizer::simplifyTypedef()
// check for typedef that can be substituted
else if (tok2->isNameOnly() &&
(Token::simpleMatch(tok2, pattern.c_str()) ||
(Token::simpleMatch(tok2, pattern.c_str(), pattern.size()) ||
(inMemberFunc && tok2->str() == typeName->str()))) {
// member function class variables don't need qualification
if (!(inMemberFunc && tok2->str() == typeName->str()) && pattern.find("::") != std::string::npos) { // has a "something ::"
@ -9410,15 +9410,15 @@ void Tokenizer::findGarbageCode() const
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
const std::set<std::string> nonConsecutiveKeywords{ "break",
"continue",
"for",
"goto",
"if",
"return",
"switch",
"throw",
"typedef",
"while" };
"continue",
"for",
"goto",
"if",
"return",
"switch",
"throw",
"typedef",
"while" };
for (const Token *tok = tokens(); tok; tok = tok->next()) {
// initialization: = {

View File

@ -96,6 +96,7 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <functional>
#include <iterator>
#include <limits>
@ -187,9 +188,9 @@ static void setConditionalValues(const Token *tok,
const char* lessThan = "<=";
if (invert)
std::swap(greaterThan, lessThan);
if (Token::simpleMatch(tok, greaterThan)) {
if (Token::simpleMatch(tok, greaterThan, strlen(greaterThan))) {
false_value = ValueFlow::Value{tok, value - 1};
} else if (Token::simpleMatch(tok, lessThan)) {
} else if (Token::simpleMatch(tok, lessThan, strlen(lessThan))) {
false_value = ValueFlow::Value{tok, value + 1};
} else {
false_value = ValueFlow::Value{tok, value};
@ -199,10 +200,10 @@ static void setConditionalValues(const Token *tok,
const char* lessThan = "<";
if (invert)
std::swap(greaterThan, lessThan);
if (Token::simpleMatch(tok, greaterThan)) {
if (Token::simpleMatch(tok, greaterThan, strlen(greaterThan))) {
true_value = ValueFlow::Value{tok, value + 1};
false_value = ValueFlow::Value{tok, value};
} else if (Token::simpleMatch(tok, lessThan)) {
} else if (Token::simpleMatch(tok, lessThan, strlen(lessThan))) {
true_value = ValueFlow::Value{tok, value - 1};
false_value = ValueFlow::Value{tok, value};
}

View File

@ -24,6 +24,7 @@
#include "tokenize.h"
#include "tokenlist.h"
#include <cstring>
class TestAstUtils : public TestFixture {
public:
@ -166,8 +167,8 @@ private:
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokens1("");
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1);
const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2);
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1));
const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2));
return ::isSameExpression(false, false, tok1, tok2, library, false, true, nullptr);
}
@ -203,8 +204,8 @@ private:
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern);
const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern);
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern));
const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern));
return ::isVariableChanged(tok1,tok2,1,false,&settings,true);
}
@ -247,8 +248,8 @@ private:
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
const Token * tok = Token::findsimplematch(tokenizer.tokens(), parentPattern);
return Token::simpleMatch(::nextAfterAstRightmostLeaf(tok), rightPattern);
const Token * tok = Token::findsimplematch(tokenizer.tokens(), parentPattern, strlen(parentPattern));
return Token::simpleMatch(::nextAfterAstRightmostLeaf(tok), rightPattern, strlen(rightPattern));
}
void nextAfterAstRightmostLeaf() {

View File

@ -25,6 +25,8 @@
#include "token.h"
#include "tokenize.h"
#include <cstring>
struct InternalError;
@ -4545,7 +4547,7 @@ private:
const Token *tok1 = TemplateSimplifier::findTemplateDeclarationEnd(_tok);
return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern));
return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern, strlen(pattern)));
}
void findTemplateDeclarationEnd() {

View File

@ -30,6 +30,7 @@
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <list>
#include <map>
#include <set>
@ -6548,7 +6549,7 @@ private:
tokenizer.tokenize(istr, filename);
const Token* tok;
for (tok = tokenizer.list.back(); tok; tok = tok->previous())
if (Token::simpleMatch(tok, pattern))
if (Token::simpleMatch(tok, pattern, strlen(pattern)))
break;
return tok->valueType() ? tok->valueType()->str() : std::string();
}

View File

@ -34,6 +34,7 @@
#include <utility>
#include <vector>
#include <cstdint>
#include <cstring>
class TestValueFlow : public TestFixture {
public:
@ -231,7 +232,7 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) {
for (const ValueFlow::Value &v : tok->values()) {
if (v.valueType == type && Token::simpleMatch(v.tokvalue, value))
if (v.valueType == type && Token::simpleMatch(v.tokvalue, value, strlen(value)))
return true;
}
}