Exemplo n.º 1
0
// default : bail out if the condition is has variable handling
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & checks)
{
    unsigned int parlevel = 0;
    for (const Token *tok2 = &tok; tok2; tok2 = tok2->next()) {
        if (tok2->str() == "(")
            ++parlevel;
        else if (tok2->str() == ")") {
            if (parlevel == 0)
                break;
            --parlevel;
        } else if (Token::Match(tok2, "[;{}]"))
            break;
        if (tok2->varId() != 0) {
            bailOutVar(checks, tok2->varId());
        }
    }

    for (std::list<ExecutionPath *>::iterator it = checks.begin(); it != checks.end();) {
        if ((*it)->varId > 0 && (*it)->numberOfIf >= 1) {
            delete *it;
            checks.erase(it++);
        } else {
            ++it;
        }
    }


    return false;
}
Exemplo n.º 2
0
    /** parse tokens */
    const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const
    {
        if (Token::Match(tok.previous(), "[;{}] const| struct| %type% * %var% ;"))
        {
            const Token * vartok = tok.tokAt(2);

            if (tok.str() == "const")
                vartok = vartok->next();

            if (tok.str() == "struct")
                vartok = vartok->next();

            if (vartok->varId() != 0)
                checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
            return vartok->next();
        }

        // Template pointer variable..
        if (Token::Match(tok.previous(), "[;{}] %type% ::|<"))
        {
            const Token * vartok = &tok;
            while (Token::Match(vartok, "%type% ::"))
                vartok = vartok->tokAt(2);
            if (Token::Match(vartok, "%type% < %type%"))
            {
                vartok = vartok->tokAt(3);
                while (vartok && (vartok->str() == "*" || vartok->isName()))
                    vartok = vartok->next();
            }
            if (vartok
                && (vartok->str() == ">" || vartok->isName())
                && Token::Match(vartok->next(), "* %var% ;|="))
            {
                vartok = vartok->tokAt(2);
                checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
                if (Token::simpleMatch(vartok->next(), "= 0 ;"))
                    setnull(checks, vartok->varId());
                return vartok->next();
            }
        }

        if (Token::simpleMatch(&tok, "try {"))
        {
            // Bail out all used variables
            unsigned int indentlevel = 0;
            for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
            {
                if (tok2->str() == "{")
                    ++indentlevel;
                else if (tok2->str() == "}")
                {
                    if (indentlevel == 0)
                        break;
                    if (indentlevel == 1 && !Token::simpleMatch(tok2,"} catch ("))
                        return tok2;
                    --indentlevel;
                }
                else if (tok2->varId())
                    bailOutVar(checks,tok2->varId());
            }
        }

        if (Token::Match(&tok, "%var% ("))
        {
            if (tok.str() == "sizeof")
                return tok.next()->link();

            // parse usage..
            std::list<const Token *> var;
            CheckNullPointer::parseFunctionCall(tok, var, 0);
            for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
                dereference(checks, *it);
        }

        else if (Token::simpleMatch(&tok, "( 0 &&"))
            return tok.link();

        if (tok.varId() != 0)
        {
            // unknown : not really used. it is passed to isPointerDeRef.
            //           if isPointerDeRef fails to determine if there
            //           is a dereference the this will be set to true.
            bool unknown = false;

            if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
                setnull(checks, tok.varId());
            else if (CheckNullPointer::isPointerDeRef(&tok, unknown))
                dereference(checks, &tok);
            else
                // TODO: Report debug warning that it's unknown if a
                // pointer is dereferenced
                bailOutVar(checks, tok.varId());
        }

        else if (tok.str() == "delete")
        {
            const Token *ret = tok.next();
            if (Token::simpleMatch(ret, "[ ]"))
                ret = ret->tokAt(2);
            if (Token::Match(ret, "%var% ;"))
                return ret->next();
        }

        return &tok;
    }
Exemplo n.º 3
0
	/** parse tokens */
	const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const {
		if (tok.varId() != 0) {
			// Pointer declaration declaration?
			if(symbolDatabase)
			{
				const Variable* var = symbolDatabase->getVariableFromVarId(tok.varId());
				if (var && var->isPointer() && var->nameToken() == &tok)
					checks.push_back(new Nullpointer(owner, var->varId(), var->name(), symbolDatabase));
			}
		}

        if (Token::simpleMatch(&tok, "try {")) {
            // Bail out all used variables
            const Token* tok2 = &tok;
            const Token* endtok = tok.linkAt(1);
            for (; tok2 && tok2 != endtok; tok2 = tok2->next()) {
                if (tok2->varId())
                    bailOutVar(checks,tok2->varId());
            }
            return tok2;
        }

        if (Token::Match(&tok, "%var% (")) {
            if (tok.str() == "sizeof" || tok.str() == "typeid")
                return tok.next()->link();

            // parse usage..
            std::list<const Token *> var;
            CheckNullPointer::parseFunctionCall(tok, var, 0);
            for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
                dereference(checks, *it);
        }

        else if (Token::simpleMatch(&tok, "( 0 &&"))
            return tok.link();

        if (tok.varId() != 0) {
            // unknown: if isPointerDeRef fails to determine if there
            //          is a dereference this will be set to true.
            bool unknown = owner->inconclusiveFlag();
            bool deref = CheckNullPointer::isPointerDeRef(&tok, unknown, symbolDatabase);

            if (deref)
                dereference(checks, &tok);
            else if (unknown && owner->inconclusiveFlag())
                dereference(checks, &tok);
            if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
                setnull(checks, tok.varId());
            else if (!deref &&
                     (!tok.previous()->isOp() || tok.previous()->str() == "&") && !tok.previous()->isAssignmentOp() &&
                     (!tok.next()->isOp() || tok.next()->str() == ">>"))
                bailOutVar(checks, tok.varId()); // If its possible that the pointers value changes, bail out.
        }

        else if (tok.str() == "delete") {
            const Token *ret = tok.next();
            if (Token::simpleMatch(ret, "[ ]"))
                ret = ret->tokAt(2);
            if (Token::Match(ret, "%var% ;"))
                return ret->next();
        }

        else if (tok.str() == "return") {
            bool unknown = owner->inconclusiveFlag();
            const Token* tok2 = &tok;
            for (; tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
                if (tok2->varId()) {
                    if (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase) || unknown)
                        dereference(checks, tok2);
                }

                // If return statement contains "?" then assume there
                // is no dangours dereferencing later
                if (tok2->str() == "?") {
                    while (tok2 && tok2->str() != ";")
                        tok2 = tok2->next();
                    return tok2;
                }
            }
        }

        return &tok;
    }