Add non-const overloads for next(), previous(), and link() (#5002)

* Add non-const overloads for next(), previous(), and link()

* Format

* Add CPPCHECKLIB
This commit is contained in:
Paul Fultz II 2023-05-01 23:55:31 -05:00 committed by GitHub
parent d5fbd552a6
commit 9d21379c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 54 deletions

View File

@ -392,7 +392,7 @@ CPPCHECKLIB const Token *findLambdaStartToken(const Token *last);
* \return nullptr or the } * \return nullptr or the }
*/ */
CPPCHECKLIB const Token *findLambdaEndToken(const Token *first); CPPCHECKLIB const Token *findLambdaEndToken(const Token *first);
Token* findLambdaEndToken(Token* first); CPPCHECKLIB Token* findLambdaEndToken(Token* first);
bool isLikelyStream(bool cpp, const Token *stream); bool isLikelyStream(bool cpp, const Token *stream);

View File

@ -52,7 +52,7 @@
#include <unordered_set> #include <unordered_set>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
SymbolDatabase::SymbolDatabase(const Tokenizer &tokenizer, const Settings &settings, ErrorLogger *errorLogger) SymbolDatabase::SymbolDatabase(Tokenizer& tokenizer, const Settings& settings, ErrorLogger* errorLogger)
: mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger) : mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger)
{ {
if (!mTokenizer.tokens()) if (!mTokenizer.tokens())
@ -1230,7 +1230,7 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
}; };
// Set variable pointers // Set variable pointers
for (const Token* tok = mTokenizer.list.front(); tok != mTokenizer.list.back(); tok = tok->next()) { for (Token* tok = mTokenizer.list.front(); tok != mTokenizer.list.back(); tok = tok->next()) {
if (!tok->isName() || tok->isKeyword() || tok->isStandardType()) if (!tok->isName() || tok->isKeyword() || tok->isStandardType())
continue; continue;
if (tok->varId()) if (tok->varId())

View File

@ -1364,17 +1364,17 @@ public:
class CPPCHECKLIB SymbolDatabase { class CPPCHECKLIB SymbolDatabase {
friend class TestSymbolDatabase; friend class TestSymbolDatabase;
public: public:
SymbolDatabase(const Tokenizer &tokenizer, const Settings &settings, ErrorLogger *errorLogger); SymbolDatabase(Tokenizer& tokenizer, const Settings& settings, ErrorLogger* errorLogger);
~SymbolDatabase(); ~SymbolDatabase();
/** @brief Information about all namespaces/classes/structures */ /** @brief Information about all namespaces/classes/structures */
std::list<Scope> scopeList; std::list<Scope> scopeList;
/** @brief Fast access to function scopes */ /** @brief Fast access to function scopes */
std::vector<const Scope *> functionScopes; std::vector<const Scope*> functionScopes;
/** @brief Fast access to class and struct scopes */ /** @brief Fast access to class and struct scopes */
std::vector<const Scope *> classAndStructScopes; std::vector<const Scope*> classAndStructScopes;
/** @brief Fast access to types */ /** @brief Fast access to types */
std::list<Type> typeList; std::list<Type> typeList;
@ -1385,21 +1385,22 @@ public:
* @param typeTok token containing variable type * @param typeTok token containing variable type
* @return pointer to type if found or NULL if not found * @return pointer to type if found or NULL if not found
*/ */
const Type *findVariableType(const Scope *start, const Token *typeTok) const; const Type* findVariableType(const Scope* start, const Token* typeTok) const;
/** /**
* @brief find a function * @brief find a function
* @param tok token of function call * @param tok token of function call
* @return pointer to function if found or NULL if not found * @return pointer to function if found or NULL if not found
*/ */
const Function *findFunction(const Token *tok) const; const Function* findFunction(const Token* tok) const;
/** For unit testing only */ /** For unit testing only */
const Scope *findScopeByName(const std::string& name) const; const Scope* findScopeByName(const std::string& name) const;
const Type* findType(const Token *startTok, const Scope *startScope, bool lookOutside = false) const; const Type* findType(const Token* startTok, const Scope* startScope, bool lookOutside = false) const;
Type* findType(const Token *startTok, Scope *startScope, bool lookOutside = false) { Type* findType(const Token* startTok, Scope* startScope, bool lookOutside = false)
return const_cast<Type*>(this->findType(startTok, const_cast<const Scope *>(startScope), lookOutside)); {
return const_cast<Type*>(this->findType(startTok, const_cast<const Scope*>(startScope), lookOutside));
} }
const Scope *findScope(const Token *tok, const Scope *startScope) const; const Scope *findScope(const Token *tok, const Scope *startScope) const;
@ -1508,7 +1509,7 @@ private:
void setValueType(Token* tok, const Variable& var, SourceLocation loc = SourceLocation::current()); void setValueType(Token* tok, const Variable& var, SourceLocation loc = SourceLocation::current());
void setValueType(Token* tok, const Enumerator& enumerator, SourceLocation loc = SourceLocation::current()); void setValueType(Token* tok, const Enumerator& enumerator, SourceLocation loc = SourceLocation::current());
const Tokenizer &mTokenizer; Tokenizer& mTokenizer;
const Settings &mSettings; const Settings &mSettings;
ErrorLogger *mErrorLogger; ErrorLogger *mErrorLogger;

View File

@ -830,10 +830,13 @@ public:
mImpl->mColumn = c; mImpl->mColumn = c;
} }
Token *next() const { Token* next() {
return mNext; return mNext;
} }
const Token* next() const {
return mNext;
}
/** /**
* Delete tokens between begin and end. E.g. if begin = 1 * Delete tokens between begin and end. E.g. if begin = 1
@ -859,10 +862,13 @@ public:
return insertToken(tokenStr, originalNameStr, true); return insertToken(tokenStr, originalNameStr, true);
} }
Token *previous() const { Token* previous() {
return mPrevious; return mPrevious;
} }
const Token* previous() const {
return mPrevious;
}
nonneg int varId() const { nonneg int varId() const {
return mImpl->mVarId; return mImpl->mVarId;
@ -1012,7 +1018,11 @@ public:
* *
* @return The token where this token links to. * @return The token where this token links to.
*/ */
Token *link() const { const Token* link() const {
return mLink;
}
Token* link() {
return mLink; return mLink;
} }

View File

@ -2603,7 +2603,7 @@ namespace {
// fixme: this is wrong // fixme: this is wrong
// skip to end of scope // skip to end of scope
if (currentScope->bodyEnd) if (currentScope->bodyEnd)
*tok = currentScope->bodyEnd->previous(); *tok = const_cast<Token*>(currentScope->bodyEnd->previous());
return false; return false;
} }
@ -2938,7 +2938,7 @@ bool Tokenizer::simplifyUsing()
if (!currentScope1) if (!currentScope1)
return substitute; // something bad happened return substitute; // something bad happened
startToken = usingEnd->next(); startToken = usingEnd->next();
endToken = currentScope->bodyEnd->next(); endToken = const_cast<Token*>(currentScope->bodyEnd->next());
if (currentScope->type == ScopeInfo3::MemberFunction) { if (currentScope->type == ScopeInfo3::MemberFunction) {
const ScopeInfo3 * temp = currentScope->findScope(currentScope->fullName); const ScopeInfo3 * temp = currentScope->findScope(currentScope->fullName);
if (temp) { if (temp) {
@ -4037,10 +4037,9 @@ void VariableMap::addVariable(const std::string& varname, bool globalNamespace)
it->second = ++mVarId; it->second = ++mVarId;
} }
static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap, bool executableScope, bool cpp, bool c)
static bool setVarIdParseDeclaration(const Token **tok, const VariableMap& variableMap, bool executableScope, bool cpp, bool c)
{ {
const Token *tok2 = *tok; Token* tok2 = *tok;
if (!tok2->isName()) if (!tok2->isName())
return false; return false;
@ -4079,7 +4078,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const VariableMap& varia
const Token *start = *tok; const Token *start = *tok;
if (Token::Match(start->previous(), "%or%|%oror%|&&|&|^|+|-|*|/")) if (Token::Match(start->previous(), "%or%|%oror%|&&|&|^|+|-|*|/"))
return false; return false;
const Token * const closingBracket = tok2->findClosingBracket(); Token* const closingBracket = tok2->findClosingBracket();
if (closingBracket == nullptr) { /* Ticket #8151 */ if (closingBracket == nullptr) { /* Ticket #8151 */
throw tok2; throw tok2;
} }
@ -4232,14 +4231,13 @@ void Tokenizer::setVarIdStructMembers(Token **tok1,
*tok1 = tok; *tok1 = tok;
} }
void Tokenizer::setVarIdClassDeclaration(Token* const startToken,
void Tokenizer::setVarIdClassDeclaration(const Token * const startToken, VariableMap& variableMap,
VariableMap &variableMap,
const nonneg int scopeStartVarId, const nonneg int scopeStartVarId,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers) std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers)
{ {
// end of scope // end of scope
const Token * const endToken = startToken->link(); Token* const endToken = startToken->link();
// determine class name // determine class name
std::string className; std::string className;
@ -4516,7 +4514,7 @@ void Tokenizer::setVarIdPass1()
return; return;
// locate the variable name.. // locate the variable name..
const Token *tok2 = (tok->isName()) ? tok : tok->next(); Token* tok2 = (tok->isName()) ? tok : tok->next();
// private: protected: public: etc // private: protected: public: etc
while (tok2 && endsWith(tok2->str(), ':')) { while (tok2 && endsWith(tok2->str(), ':')) {

View File

@ -579,8 +579,8 @@ private:
void unsupportedTypedef(const Token *tok) const; void unsupportedTypedef(const Token *tok) const;
void setVarIdClassDeclaration(const Token * const startToken, // cppcheck-suppress functionConst // has side effects void setVarIdClassDeclaration(Token* const startToken, // cppcheck-suppress functionConst // has side effects
VariableMap &variableMap, VariableMap& variableMap,
const nonneg int scopeStartVarId, const nonneg int scopeStartVarId,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers); std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers);
@ -645,6 +645,10 @@ public:
return list.front(); return list.front();
} }
Token* tokens() {
return list.front();
}
/** /**
* Helper function to check whether number is one (1 or 0.1E+1 or 1E+0) or not? * Helper function to check whether number is one (1 or 0.1E+1 or 1E+0) or not?
* @param s the string to check * @param s the string to check

View File

@ -943,7 +943,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
} }
} }
const Token* const tok2 = tok; Token* const tok2 = tok;
if (tok->strAt(1) != "]") if (tok->strAt(1) != "]")
compileBinOp(tok, state, compileExpression); compileBinOp(tok, state, compileExpression);
else else
@ -1414,7 +1414,7 @@ static Token * createAstAtToken(Token *tok, bool cpp)
{ {
// skip function pointer declaration // skip function pointer declaration
if (Token::Match(tok, "%type%") && !Token::Match(tok, "return|throw|if|while|new|delete")) { if (Token::Match(tok, "%type%") && !Token::Match(tok, "return|throw|if|while|new|delete")) {
const Token* type = tok; Token* type = tok;
while (Token::Match(type, "%type%|*|&|<")) { while (Token::Match(type, "%type%|*|&|<")) {
if (type->str() == "<") { if (type->str() == "<") {
if (type->link()) if (type->link())
@ -1640,7 +1640,7 @@ static Token * createAstAtToken(Token *tok, bool cpp)
Token * const tok1 = tok; Token * const tok1 = tok;
AST_state state(cpp); AST_state state(cpp);
compileExpression(tok, state); compileExpression(tok, state);
const Token * const endToken = tok; Token* const endToken = tok;
if (endToken == tok1 || !endToken) if (endToken == tok1 || !endToken)
return tok1; return tok1;

View File

@ -1933,7 +1933,7 @@ static void valueFlowEnumValue(SymbolDatabase * symboldatabase, const Settings *
for (Enumerator & enumerator : scope.enumeratorList) { for (Enumerator & enumerator : scope.enumeratorList) {
if (enumerator.start) { if (enumerator.start) {
Token *rhs = enumerator.start->previous()->astOperand2(); Token* rhs = const_cast<Token*>(enumerator.start->previous()->astOperand2());
ValueFlow::valueFlowConstantFoldAST(rhs, settings); ValueFlow::valueFlowConstantFoldAST(rhs, settings);
if (rhs && rhs->hasKnownIntValue()) { if (rhs && rhs->hasKnownIntValue()) {
enumerator.value = rhs->values().front().intvalue; enumerator.value = rhs->values().front().intvalue;
@ -5189,10 +5189,10 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
} }
} }
for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "if (")) if (!Token::simpleMatch(tok, "if ("))
continue; continue;
const Token * parenTok = tok->next(); Token* parenTok = tok->next();
if (!Token::simpleMatch(parenTok->link(), ") {")) if (!Token::simpleMatch(parenTok->link(), ") {"))
continue; continue;
Token * blockTok = parenTok->link()->tokAt(1); Token * blockTok = parenTok->link()->tokAt(1);
@ -5255,7 +5255,6 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
} }
} }
} }
} }
} }
} }
@ -6150,7 +6149,7 @@ struct ConditionHandler {
if (tok->hasKnownIntValue()) if (tok->hasKnownIntValue())
return; return;
const Token* top = tok->astTop(); Token* top = tok->astTop();
if (Token::Match(top, "%assign%")) if (Token::Match(top, "%assign%"))
return; return;
@ -6291,7 +6290,7 @@ struct ConditionHandler {
const Settings* settings, const Settings* settings,
const std::set<const Scope*>& skippedFunctions) const { const std::set<const Scope*>& skippedFunctions) const {
traverseCondition(tokenlist, symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* condTok, const Scope* scope) { traverseCondition(tokenlist, symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* condTok, const Scope* scope) {
const Token* top = condTok->astTop(); Token* top = condTok->astTop();
const MathLib::bigint path = cond.getPath(); const MathLib::bigint path = cond.getPath();
const bool allowKnown = path == 0; const bool allowKnown = path == 0;
@ -7507,7 +7506,7 @@ static void valueFlowSubFunction(TokenList* tokenlist, SymbolDatabase* symboldat
const Function* function = scope->function; const Function* function = scope->function;
if (!function) if (!function)
continue; continue;
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (tok->isKeyword() || !Token::Match(tok, "%name% (")) if (tok->isKeyword() || !Token::Match(tok, "%name% ("))
continue; continue;
@ -8296,8 +8295,8 @@ static void valueFlowIterators(TokenList *tokenlist, const Settings *settings)
continue; continue;
if (!astIsContainer(tok)) if (!astIsContainer(tok))
continue; continue;
const Token* ftok = nullptr; Token* ftok = nullptr;
const Library::Container::Yield yield = findIteratorYield(tok, &ftok, settings); const Library::Container::Yield yield = findIteratorYield(tok, const_cast<const Token**>(&ftok), settings);
if (ftok) { if (ftok) {
ValueFlow::Value v(0); ValueFlow::Value v(0);
v.setKnown(); v.setKnown();
@ -8573,39 +8572,39 @@ static void valueFlowContainerSize(TokenList* tokenlist,
} }
if (!staticSize && nonLocal) if (!staticSize && nonLocal)
continue; continue;
if (var->nameToken()->hasKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE)) Token* nameToken = const_cast<Token*>(var->nameToken());
if (nameToken->hasKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))
continue; continue;
if (!staticSize) { if (!staticSize) {
if (!Token::Match(var->nameToken(), "%name% ;") && if (!Token::Match(nameToken, "%name% ;") &&
!(Token::Match(var->nameToken(), "%name% {") && !(Token::Match(nameToken, "%name% {") && Token::simpleMatch(nameToken->next()->link(), "} ;")) &&
Token::simpleMatch(var->nameToken()->next()->link(), "} ;")) && !Token::Match(nameToken, "%name% ("))
!Token::Match(var->nameToken(), "%name% ("))
continue; continue;
} }
if (var->nameToken()->astTop() && Token::Match(var->nameToken()->astTop()->previous(), "for|while")) if (nameToken->astTop() && Token::Match(nameToken->astTop()->previous(), "for|while"))
known = !isVariableChanged(var, settings, true); known = !isVariableChanged(var, settings, true);
std::vector<ValueFlow::Value> values{ValueFlow::Value{size}}; std::vector<ValueFlow::Value> values{ValueFlow::Value{size}};
values.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; values.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
if (known) if (known)
values.back().setKnown(); values.back().setKnown();
if (!staticSize) { if (!staticSize) {
if (Token::simpleMatch(var->nameToken()->next(), "{")) { if (Token::simpleMatch(nameToken->next(), "{")) {
Token* initList = var->nameToken()->next(); Token* initList = nameToken->next();
valueFlowContainerSetTokValue(tokenlist, settings, var->nameToken(), initList); valueFlowContainerSetTokValue(tokenlist, settings, nameToken, initList);
values = getInitListSize(initList, var->valueType(), settings, known); values = getInitListSize(initList, var->valueType(), settings, known);
} else if (Token::simpleMatch(var->nameToken()->next(), "(")) { } else if (Token::simpleMatch(nameToken->next(), "(")) {
const Token* constructorArgs = var->nameToken()->next(); const Token* constructorArgs = nameToken->next();
values = getContainerSizeFromConstructor(constructorArgs, var->valueType(), settings, known); values = getContainerSizeFromConstructor(constructorArgs, var->valueType(), settings, known);
} }
} }
if (constSize) { if (constSize) {
valueFlowForwardConst(var->nameToken()->next(), var->scope()->bodyEnd, var, values, settings); valueFlowForwardConst(nameToken->next(), var->scope()->bodyEnd, var, values, settings);
continue; continue;
} }
for (const ValueFlow::Value& value : values) { for (const ValueFlow::Value& value : values) {
valueFlowForward(var->nameToken()->next(), var->nameToken(), value, tokenlist, settings); valueFlowForward(nameToken->next(), var->nameToken(), value, tokenlist, settings);
} }
} }

View File

@ -45,6 +45,10 @@ public:
tokenizer.tokenize(iss, cpp ? "test.cpp" : "test.c"); tokenizer.tokenize(iss, cpp ? "test.cpp" : "test.c");
} }
Token* tokens() {
return tokenizer.tokens();
}
const Token* tokens() const { const Token* tokens() const {
return tokenizer.tokens(); return tokenizer.tokens();
} }