| 1440 | } |
| 1441 | |
| 1442 | bool CheckUninitVarImpl::isMemberVariableAssignment(const Token *tok, const std::string &membervar) const |
| 1443 | { |
| 1444 | if (Token::Match(tok, "%name% . %name%") && tok->strAt(2) == membervar) { |
| 1445 | if (Token::Match(tok->tokAt(3), "[=.[]")) |
| 1446 | return true; |
| 1447 | if (Token::Match(tok->tokAt(-2), "[(,=] &")) |
| 1448 | return true; |
| 1449 | if (isLikelyStreamRead(tok->previous())) |
| 1450 | return true; |
| 1451 | if ((tok->previous() && tok->previous()->isConstOp()) || Token::Match(tok->previous(), "[|=")) |
| 1452 | ; // member variable usage |
| 1453 | else if (tok->tokAt(3)->isConstOp()) |
| 1454 | ; // member variable usage |
| 1455 | else if (Token::Match(tok->previous(), "[(,] %name% . %name% [,)]") && |
| 1456 | 1 == isFunctionParUsage(tok, false, NO_ALLOC)) { |
| 1457 | return false; |
| 1458 | } else |
| 1459 | return true; |
| 1460 | } else if (tok->strAt(1) == "=") |
| 1461 | return true; |
| 1462 | else if (Token::Match(tok, "%var% . %name% (")) { |
| 1463 | const Token *ftok = tok->tokAt(2); |
| 1464 | if (!ftok->function() || !ftok->function()->isConst()) |
| 1465 | // TODO: Try to determine if membervar is assigned in method |
| 1466 | return true; |
| 1467 | } else if (tok->strAt(-1) == "&") { |
| 1468 | if (Token::Match(tok->tokAt(-2), "[(,] & %name%")) { |
| 1469 | // locate start parentheses in function call.. |
| 1470 | int argumentNumber = 0; |
| 1471 | const Token *ftok = tok; |
| 1472 | while (ftok && !Token::Match(ftok, "[;{}(]")) { |
| 1473 | if (ftok->str() == ")") |
| 1474 | ftok = ftok->link(); |
| 1475 | else if (ftok->str() == ",") |
| 1476 | ++argumentNumber; |
| 1477 | ftok = ftok->previous(); |
| 1478 | } |
| 1479 | |
| 1480 | // is this a function call? |
| 1481 | ftok = ftok ? ftok->previous() : nullptr; |
| 1482 | if (Token::Match(ftok, "%name% (")) { |
| 1483 | // check how function handle uninitialized data arguments.. |
| 1484 | const Function *function = ftok->function(); |
| 1485 | |
| 1486 | if (!function) { |
| 1487 | // Function definition not seen, check if direction is specified in the library configuration |
| 1488 | const Library::ArgumentChecks::Direction argDirection = mSettings.library.getArgDirection(ftok, 1 + argumentNumber); |
| 1489 | if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) |
| 1490 | return false; |
| 1491 | if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT) |
| 1492 | return true; |
| 1493 | } |
| 1494 | |
| 1495 | const Variable *arg = function ? function->getArgumentVar(argumentNumber) : nullptr; |
| 1496 | const Token *argStart = arg ? arg->typeStartToken() : nullptr; |
| 1497 | while (argStart && argStart->previous() && argStart->previous()->isName()) |
| 1498 | argStart = argStart->previous(); |
| 1499 | if (Token::Match(argStart, "const struct| %type% * const| %name% [,)]")) |
nothing calls this directly
no test coverage detected