Example #1
0
void CheckType::checkLongCast()
{
    if (!_settings->isEnabled("style"))
        return;

    // Assignments..
    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
        if (!Token::Match(tok, "%var% ="))
            continue;
        if (!tok->variable() || !tok->variable()->isConst() || tok->variable()->typeStartToken()->str() != "long")
            continue;
        if (!tok->variable()->typeStartToken()->originalName().empty())
            continue;
        if (Token::Match(tok->next()->astOperand2(), "*|<<") && astIsIntResult(tok->next()->astOperand2()))
            longCastAssignError(tok);
    }

    // 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];

        // function must return long data
        const Token * def = scope->classDef;
        bool islong = false;
        while (Token::Match(def, "%type%|::")) {
            if (def->str() == "long" && def->originalName().empty()) {
                islong = true;
                break;
            }
            def = def->previous();
        }
        if (!islong)
            continue;

        // find return statement
        // todo.. this is slow, we should only check last statement in each child scope
        const Token *ret = nullptr;
        for (const Token *tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
            if (tok->str() == "return") {
                if (!ret)
                    ret = tok;
                else {
                    ret =  nullptr;
                    break;
                }
            }
        }

        if (ret && Token::Match(ret->astOperand1(), "*|<<") && astIsIntResult(ret->astOperand1()))
            longCastReturnError(ret);
    }
}
Example #2
0
void CheckType::checkLongCast()
{
    if (!_settings->isEnabled("style"))
        return;

    // Assignments..
    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
        if (tok->str() != "=" || !Token::Match(tok->astOperand2(), "*|<<"))
            continue;

        const ValueType *lhstype = tok->astOperand1() ? tok->astOperand1()->valueType() : nullptr;
        const ValueType *rhstype = tok->astOperand2()->valueType();

        if (!lhstype || !rhstype)
            continue;

        // assign int result to long/longlong const nonpointer?
        if (rhstype->type == ValueType::Type::INT &&
            rhstype->pointer == 0U &&
            rhstype->originalTypeName.empty() &&
            (lhstype->type == ValueType::Type::LONG || lhstype->type == ValueType::Type::LONGLONG) &&
            lhstype->pointer == 0U &&
            lhstype->constness == 1U &&
            lhstype->originalTypeName.empty())
            longCastAssignError(tok);
    }

    // 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];

        // function must return long data
        const Token * def = scope->classDef;
        bool islong = false;
        while (Token::Match(def, "%type%|::")) {
            if (def->str() == "long" && def->originalName().empty()) {
                islong = true;
                break;
            }
            def = def->previous();
        }
        if (!islong)
            continue;

        // return statements
        const Token *ret = nullptr;
        for (const Token *tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
            if (tok->str() == "return") {
                if (Token::Match(tok->astOperand1(), "<<|*")) {
                    const ValueType *type = tok->astOperand1()->valueType();
                    if (type && type->type == ValueType::Type::INT && type->pointer == 0U && type->originalTypeName.empty())
                        ret = tok;
                }
                // All return statements must have problem otherwise no warning
                if (ret != tok) {
                    ret = nullptr;
                    break;
                }
            }
        }

        if (ret)
            longCastReturnError(ret);
    }
}