Ejemplo n.º 1
0
//---------------------------------------------------------------------------
// memset(p, y, 0 /* bytes to fill */) <- 2nd and 3rd arguments inverted
//---------------------------------------------------------------------------
void CheckFunctions::memsetZeroBytes()
{
// FIXME:
//  Replace this with library configuration.
//  For instance:
//     <arg nr="3">
//       <warn knownIntValue="0" severity="warning" msg="..."/>
//     </arg>

    if (!_settings->isEnabled(Settings::WARNING))
        return;

    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, "memset|wmemset (") && (numberOfArguments(tok)==3)) {
                const std::vector<const Token *> &arguments = getArguments(tok);
                if (WRONG_DATA(arguments.size() != 3U, tok))
                    continue;
                const Token* lastParamTok = arguments[2];
                if (lastParamTok->str() == "0")
                    memsetZeroBytesError(tok);
            }
        }
    }
}
Ejemplo n.º 2
0
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive)
{
    if (!tok)
        return false;

    // address of variable
    const bool addressOf = Token::simpleMatch(tok->previous(), "&");

    // passing variable to subfunction?
    if (Token::Match(tok->tokAt(-2), ") & %name% [,)]") && Token::Match(tok->linkAt(-2)->previous(), "[,(] ("))
        ;
    else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[(,] &| %name% [,)]"))
        ;
    else if (Token::Match(tok->tokAt(addressOf?-2:-1), "[?:] &| %name% [:,)]")) {
        const Token *parent = tok->astParent();
        if (parent == tok->previous() && parent->str() == "&")
            parent = parent->astParent();
        while (Token::Match(parent, "[?:]"))
            parent = parent->astParent();
        while (Token::simpleMatch(parent, ","))
            parent = parent->astParent();
        if (!parent || parent->str() != "(")
            return false;
    } else
        return false;

    // reinterpret_cast etc..
    if (Token::Match(tok->tokAt(-3), "> ( & %name% ) [,)]") &&
        tok->linkAt(-3) &&
        Token::Match(tok->linkAt(-3)->tokAt(-2), "[,(] %type% <"))
        tok = tok->linkAt(-3);

    // goto start of function call and get argnr
    unsigned int argnr = 0;
    while (tok && tok->str() != "(") {
        if (tok->str() == ",")
            ++argnr;
        else if (tok->str() == ")")
            tok = tok->link();
        tok = tok->previous();
    }
    tok = tok ? tok->previous() : nullptr;
    if (tok && tok->link() && tok->str() == ">")
        tok = tok->link()->previous();
    if (!Token::Match(tok, "%name% [(<]"))
        return false; // not a function => variable not changed

    // Constructor call
    if (tok->variable() && tok->variable()->nameToken() == tok) {
        // Find constructor..
        const unsigned int argCount = numberOfArguments(tok);
        const Scope *typeScope = tok->variable()->typeScope();
        if (typeScope) {
            for (std::list<Function>::const_iterator it = typeScope->functionList.begin(); it != typeScope->functionList.end(); ++it) {
                if (!it->isConstructor() || it->argCount() < argCount)
                    continue;
                const Variable *arg = it->getArgumentVar(argnr);
                if (arg && arg->isReference() && !arg->isConst())
                    return true;
            }
            return false;
        }
        if (inconclusive)
            *inconclusive = true;
        return false;
    }

    if (!tok->function()) {
        // if the library says 0 is invalid
        // => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic)
        if (!addressOf && settings && settings->library.isnullargbad(tok, 1+argnr))
            return false;
        // addressOf => inconclusive
        if (!addressOf) {
            if (inconclusive != nullptr)
                *inconclusive = true;
            return false;
        }
        return true;
    }

    const Variable *arg = tok->function()->getArgumentVar(argnr);

    if (addressOf) {
        if (!(arg && arg->isConst()))
            return true;
        // If const is applied to the pointer, then the value can still be modified
        if (arg && Token::simpleMatch(arg->typeEndToken(), "* const"))
            return true;
    }

    return arg && !arg->isConst() && arg->isReference();
}