MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / findStartToken

Function findStartToken

lib/valueflow.cpp:5960–6015  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5958}
5959
5960static Token* findStartToken(const Variable* var, Token* start, const Library& library)
5961{
5962 std::vector<Token*> uses = findAllUsages(var, start, library);
5963 if (uses.empty())
5964 return start;
5965 Token* first = uses.front();
5966 if (Token::findmatch(start, "goto|asm|setjmp|longjmp", first))
5967 return start;
5968 if (first != var->nameToken()) {
5969 // if this is lhs in assignment then set first to the first token in LHS expression
5970 Token* temp = first;
5971 while (Token::Match(temp->astParent(), "[&*(]") && precedes(temp->astParent(), temp))
5972 temp = temp->astParent();
5973 if (Token::simpleMatch(temp->astParent(), "=") && precedes(temp, temp->astParent()))
5974 first = temp;
5975 }
5976 // If there is only one usage
5977 if (uses.size() == 1)
5978 return first->previous();
5979 const Scope* scope = first->scope();
5980 // If first usage is in variable scope
5981 if (scope == var->scope()) {
5982 bool isLoopExpression = false;
5983 for (const Token* parent = first; parent; parent = parent->astParent()) {
5984 if (Token::simpleMatch(parent->astParent(), ";") &&
5985 Token::simpleMatch(parent->astParent()->astParent(), ";") &&
5986 Token::simpleMatch(parent->astParent()->astParent()->astParent(), "(") &&
5987 Token::simpleMatch(parent->astParent()->astParent()->astParent()->astOperand1(), "for (") &&
5988 parent == parent->astParent()->astParent()->astParent()->astOperand2()->astOperand2()->astOperand2()) {
5989 isLoopExpression = true;
5990 }
5991 }
5992 return isLoopExpression ? start : first->previous();
5993 }
5994 // If all uses are in the same scope
5995 if (std::all_of(uses.begin() + 1, uses.end(), [&](const Token* tok) {
5996 return tok->scope() == scope;
5997 }))
5998 return first->previous();
5999 // Compute the outer scope
6000 while (scope && scope->nestedIn != var->scope()) {
6001 if (scope->type == ScopeType::eLambda && !Token::simpleMatch(scope->bodyEnd, "} ("))
6002 return start;
6003 scope = scope->nestedIn;
6004 }
6005 if (!scope || (scope->type == ScopeType::eLambda && !Token::simpleMatch(scope->bodyEnd, "} (")))
6006 return start;
6007 auto* tok = const_cast<Token*>(scope->bodyStart);
6008 if (!tok)
6009 return start;
6010 if (Token::simpleMatch(tok->tokAt(-2), "} else {"))
6011 tok = tok->linkAt(-2);
6012 if (Token::simpleMatch(tok->previous(), ") {"))
6013 return tok->linkAt(-1)->previous();
6014 return tok;
6015}
6016
6017static void valueFlowUninit(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings)

Callers 1

valueFlowUninitFunction · 0.85

Calls 15

findAllUsagesFunction · 0.85
precedesFunction · 0.85
frontMethod · 0.80
astParentMethod · 0.80
scopeMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
linkAtMethod · 0.80
simpleMatchFunction · 0.70
emptyMethod · 0.45
nameTokenMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected