Refactor CheckFunctions::invalidFunctionUsage
This commit is contained in:
parent
1422487769
commit
3fbcc0cd3b
|
@ -452,3 +452,22 @@ int numberOfArguments(const Token *start)
|
||||||
}
|
}
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void getArgumentsRecursive(const Token *tok, std::vector<const Token *> *arguments)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return;
|
||||||
|
if (tok->str() == ",") {
|
||||||
|
getArgumentsRecursive(tok->astOperand1(), arguments);
|
||||||
|
getArgumentsRecursive(tok->astOperand2(), arguments);
|
||||||
|
} else {
|
||||||
|
arguments->push_back(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const Token *> getArguments(const Token *ftok)
|
||||||
|
{
|
||||||
|
std::vector<const Token *> arguments;
|
||||||
|
getArgumentsRecursive(ftok->next()->astOperand2(), &arguments);
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Settings;
|
class Settings;
|
||||||
class Library;
|
class Library;
|
||||||
|
@ -91,4 +92,9 @@ bool isVariableChanged(const Token *start, const Token *end, const unsigned int
|
||||||
*/
|
*/
|
||||||
int numberOfArguments(const Token *start);
|
int numberOfArguments(const Token *start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get arguments (AST)
|
||||||
|
*/
|
||||||
|
std::vector<const Token *> getArguments(const Token *ftok);
|
||||||
|
|
||||||
#endif // astutilsH
|
#endif // astutilsH
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "checkfunctions.h"
|
#include "checkfunctions.h"
|
||||||
|
#include "astutils.h"
|
||||||
#include "symboldatabase.h"
|
#include "symboldatabase.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -87,38 +88,31 @@ void CheckFunctions::invalidFunctionUsage()
|
||||||
for (std::size_t i = 0; i < functions; ++i) {
|
for (std::size_t i = 0; i < functions; ++i) {
|
||||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||||
if (!tok->isName() || !Token::Match(tok, "%name% ( !!)"))
|
if (!Token::Match(tok, "%name% ( !!)"))
|
||||||
continue;
|
continue;
|
||||||
const Token * const functionToken = tok;
|
const Token * const functionToken = tok;
|
||||||
int argnr = 1;
|
const std::vector<const Token *> arguments = getArguments(tok);
|
||||||
const Token *argtok = tok->tokAt(2);
|
for (unsigned int argnr = 1; argnr <= arguments.size(); ++argnr) {
|
||||||
do {
|
const Token * const argtok = arguments[argnr-1];
|
||||||
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::Match(var->variable()->typeStartToken(), "bool|_Bool"))) {
|
|
||||||
if (_settings->library.isboolargbad(functionToken, argnr))
|
|
||||||
invalidFunctionArgBoolError(top, functionToken->str(), argnr);
|
|
||||||
|
|
||||||
// Are the values 0 and 1 valid?
|
// check <valid>...</valid>
|
||||||
else if (!_settings->library.isargvalid(functionToken, argnr, 0))
|
if (argtok->hasKnownIntValue() &&
|
||||||
invalidFunctionArgError(top, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr));
|
!_settings->library.isargvalid(functionToken,argnr,argtok->values().front().intvalue)) {
|
||||||
else if (!_settings->library.isargvalid(functionToken, argnr, 1))
|
// TODO: Warn about possible values
|
||||||
invalidFunctionArgError(top, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr));
|
invalidFunctionArgError(argtok, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
argnr++;
|
|
||||||
argtok = argtok->nextArgument();
|
if (astIsBool(argtok)) {
|
||||||
} while (argtok && argtok->str() != ")");
|
// 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, _settings->library.validarg(functionToken, argnr));
|
||||||
|
else if (!_settings->library.isargvalid(functionToken, argnr, 1))
|
||||||
|
invalidFunctionArgError(argtok, functionToken->str(), argnr, _settings->library.validarg(functionToken, argnr));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue