Exemple #1
0
void CheckType::checkSignConversion()
{
    if (!_settings->isEnabled("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 (!tok->isArithmeticalOp() || Token::Match(tok,"+|-"))
                continue;

            // Is result unsigned?
            if (!(tok->valueType() && tok->valueType()->sign == ValueType::Sign::UNSIGNED))
                continue;

            // Check if an operand can be negative..
            std::stack<const Token *> tokens;
            tokens.push(tok->astOperand1());
            tokens.push(tok->astOperand2());
            while (!tokens.empty()) {
                const Token *tok1 = tokens.top();
                tokens.pop();
                if (!tok1)
                    continue;
                if (!tok1->getValueLE(-1,_settings))
                    continue;
                if (tok1->valueType() && tok1->valueType()->sign != ValueType::Sign::UNSIGNED)
                    signConversionError(tok1, tok1->isNumber());
            }
        }
    }
}
void CheckType::checkSignConversion()
{
    if (!_settings->isEnabled("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 (!tok->isArithmeticalOp() || Token::Match(tok,"+|-"))
                continue;

            unsigned int size = 0;
            char sign = 0;
            if (!astGetSizeSign(_settings, tok, &size, &sign))
                continue;

            if (sign != 'u')
                continue;

            // Check if there are signed operands that can be negative..
            std::stack<const Token *> tokens;
            tokens.push(tok->astOperand1());
            tokens.push(tok->astOperand2());
            while (!tokens.empty()) {
                const Token *tok1 = tokens.top();
                tokens.pop();
                if (!tok1)
                    continue;
                if (tok1->str() == "(")
                    continue; // Todo: properly handle casts, function calls, etc
                const Variable *var = tok1->variable();
                if (var && tok1->getValueLE(-1,_settings)) {
                    bool signedvar = true;  // assume that variable is signed since it can have a negative value
                    for (const Token *type = var->typeStartToken();; type = type->next()) {
                        if (type->isUnsigned()) {
                            signedvar = false;
                            break;
                        }
                        if (type->isSigned())
                            break;
                        if (type->isName() && !Token::Match(type, "char|short|int|long|const")) {
                            signedvar = false;
                            break;
                        }
                        if (type == var->typeEndToken())
                            break;
                    }
                    if (signedvar) {
                        signConversionError(tok1);
                        break;
                    }
                }
            }
        }
    }
}