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

Function valueFlowSwitchVariable

lib/valueflow.cpp:5551–5624  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5549}
5550
5551static void valueFlowSwitchVariable(const TokenList& tokenlist,
5552 const SymbolDatabase& symboldatabase,
5553 ErrorLogger& errorLogger,
5554 const Settings& settings)
5555{
5556 for (const Scope& scope : symboldatabase.scopeList) {
5557 if (scope.type != ScopeType::eSwitch)
5558 continue;
5559 if (!Token::Match(scope.classDef, "switch ( %var% ) {"))
5560 continue;
5561 const Token* vartok = scope.classDef->tokAt(2);
5562 const Variable* var = vartok->variable();
5563 if (!var)
5564 continue;
5565
5566 // bailout: global non-const variables
5567 if (!(var->isLocal() || var->isArgument()) && !var->isConst()) {
5568 if (settings.debugwarnings)
5569 bailout(tokenlist, errorLogger, vartok, "switch variable " + var->name() + " is global");
5570 continue;
5571 }
5572
5573 for (const Token* tok = scope.bodyStart->next(); tok != scope.bodyEnd; tok = tok->next()) {
5574 if (tok->str() == "{") {
5575 tok = tok->link();
5576 continue;
5577 }
5578 if (Token::Match(tok, "case %num% :")) {
5579 std::list<ValueFlow::Value> values;
5580 values.emplace_back(MathLib::toBigNumber(tok->tokAt(1)));
5581 values.back().condition = tok;
5582 values.back().errorPath.emplace_back(tok,
5583 "case " + tok->strAt(1) + ": " + vartok->str() + " is " +
5584 tok->strAt(1) + " here.");
5585 bool known = false;
5586 if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) &&
5587 !Token::Match(tok->tokAt(3), ";| case"))
5588 known = true;
5589 while (Token::Match(tok->tokAt(3), ";| case %num% :")) {
5590 known = false;
5591 tok = tok->tokAt(3);
5592 if (!tok->isName())
5593 tok = tok->next();
5594 values.emplace_back(MathLib::toBigNumber(tok->tokAt(1)));
5595 values.back().condition = tok;
5596 values.back().errorPath.emplace_back(tok,
5597 "case " + tok->strAt(1) + ": " + vartok->str() + " is " +
5598 tok->strAt(1) + " here.");
5599 }
5600 for (auto val = values.cbegin(); val != values.cend(); ++val) {
5601 valueFlowReverse(tokenlist, const_cast<Token*>(scope.classDef), vartok, *val, errorLogger, settings);
5602 }
5603 if (vartok->variable()->scope()) {
5604 if (known)
5605 values.back().setKnown();
5606
5607 // FIXME We must check if there is a return. See #9276
5608 /*

Callers 1

setValuesMethod · 0.85

Calls 9

valueFlowReverseFunction · 0.85
variableMethod · 0.80
isConstMethod · 0.80
nextMethod · 0.80
scopeMethod · 0.80
simpleMatchFunction · 0.70
tokAtMethod · 0.45
nameMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected