//--------------------------------------------------------------------------- // Check <valid> and <not-bool> //--------------------------------------------------------------------------- void CheckFunctions::invalidFunctionUsage() { const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { if (!Token::Match(tok, "%name% ( !!)")) continue; const Token * const functionToken = tok; const std::vector<const Token *> arguments = getArguments(tok); for (unsigned int argnr = 1; argnr <= arguments.size(); ++argnr) { const Token * const argtok = arguments[argnr-1]; // check <valid>...</valid> const ValueFlow::Value *invalidValue = argtok->getInvalidValue(functionToken,argnr,_settings); if (invalidValue) { invalidFunctionArgError(argtok, functionToken->next()->astOperand1()->expressionString(), argnr, invalidValue, _settings->library.validarg(functionToken, argnr)); } if (astIsBool(argtok)) { // check <not-bool> if (_settings->library.isboolargbad(functionToken, argnr)) invalidFunctionArgBoolError(argtok, functionToken->str(), argnr); // Are the values 0 and 1 valid? else if (!_settings->library.isargvalid(functionToken, argnr, 0)) invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, _settings->library.validarg(functionToken, argnr)); else if (!_settings->library.isargvalid(functionToken, argnr, 1)) invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, _settings->library.validarg(functionToken, argnr)); } } } } }
//--------------------------------------------------------------------------- // strtol(str, 0, radix) <- radix must be 0 or 2-36 //--------------------------------------------------------------------------- void CheckFunctions::invalidFunctionUsage() { const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t i = 0; i < functions; ++i) { const Scope * scope = symbolDatabase->functionScopes[i]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { if (!tok->isName() || !Token::Match(tok, "%name% ( !!)")) continue; const Token * const functionToken = tok; int argnr = 1; const Token *argtok = tok->tokAt(2); do { if (Token::Match(argtok, "%num% [,)]")) { if (MathLib::isInt(argtok->str()) && !_settings->library.isargvalid(functionToken, argnr, MathLib::toLongNumber(argtok->str()))) invalidFunctionArgError(argtok, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr)); } else { const Token *top = argtok; while (top->astParent() && top->astParent()->str() != "," && top->astParent() != tok->next()) top = top->astParent(); const Token *var = top; while (Token::Match(var, ".|::")) var = var->astOperand2(); if (Token::Match(top, "%comp%|%oror%|&&|!|true|false") || (var && var->variable() && Token::simpleMatch(var->variable()->typeStartToken(), "bool"))) { if (_settings->library.isboolargbad(functionToken, argnr)) invalidFunctionArgBoolError(top, functionToken->str(), argnr); // Are the values 0 and 1 valid? else if (!_settings->library.isargvalid(functionToken, argnr, 0)) invalidFunctionArgError(top, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr)); else if (!_settings->library.isargvalid(functionToken, argnr, 1)) invalidFunctionArgError(top, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr)); } } argnr++; argtok = argtok->nextArgument(); } while (argtok && argtok->str() != ")"); } } }