ValueType: Handle bit operations, sizeof better. Use ValueType in astIsFloat().

This commit is contained in:
Daniel Marjamäki 2015-10-11 12:20:40 +02:00
parent 5b082aa799
commit ac9cb87e04
4 changed files with 46 additions and 70 deletions

View File

@ -71,43 +71,10 @@ bool astIsIntegral(const Token *tok, bool unknown)
bool astIsFloat(const Token *tok, bool unknown)
{
// TODO: handle arrays
if (tok->isNumber())
return MathLib::isFloat(tok->str());
if (tok->isName()) {
if (tok->variable())
return tok->variable()->isFloatingType();
const ValueType *vt = tok ? tok->valueType() : nullptr;
if (!vt)
return unknown;
}
if (tok->str() == "(") {
// cast
if (Token::Match(tok, "( const| float|double )"))
return true;
// Function call
if (tok->previous()->function())
return Token::Match(tok->previous()->function()->retDef, "float|double");
if (tok->strAt(-1) == "sizeof")
return false;
return unknown;
}
if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::"))
return astIsFloat(tok->astOperand2(), unknown);
if (tok->astOperand1() && tok->str() != "?" && astIsFloat(tok->astOperand1(), unknown))
return true;
if (tok->astOperand2() && astIsFloat(tok->astOperand2(), unknown))
return true;
if (tok->isOp())
return false;
return unknown;
return vt->type >= ValueType::Type::FLOAT && vt->pointer == 0U;
}
std::string astCanonicalType(const Token *expr)

View File

@ -3744,37 +3744,41 @@ static void setValueType(Token *tok, const ValueType &valuetype)
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U));
return;
}
if (vt1->isIntegral() && vt2->isIntegral()) {
ValueType::Type t;
ValueType::Sign s;
std::string originalTypeName;
if (vt1->type == vt2->type) {
t = vt1->type;
if (vt1->sign == ValueType::Sign::UNSIGNED || vt2->sign == ValueType::Sign::UNSIGNED)
s = ValueType::Sign::UNSIGNED;
else if (vt1->sign == ValueType::Sign::UNKNOWN_SIGN || vt2->sign == ValueType::Sign::UNKNOWN_SIGN)
s = ValueType::Sign::UNKNOWN_SIGN;
else
s = ValueType::Sign::SIGNED;
originalTypeName = (vt1->originalTypeName.empty() ? vt2 : vt1)->originalTypeName;
} else if (vt1->type > vt2->type) {
t = vt1->type;
s = vt1->sign;
originalTypeName = vt1->originalTypeName;
} else {
t = vt2->type;
s = vt2->sign;
originalTypeName = vt2->originalTypeName;
}
if (t < ValueType::Type::INT) {
t = ValueType::Type::INT;
s = ValueType::Sign::SIGNED;
originalTypeName.clear();
}
}
setValueType(parent, ValueType(s, t, 0U, 0U, originalTypeName));
return;
if (vt2 &&
vt1->isIntegral() && vt1->pointer == 0U &&
vt2->isIntegral() && vt2->pointer == 0U &&
(parent->isArithmeticalOp() ||parent->tokType() == Token::eBitOp)) {
ValueType vt;
if (vt1->type == vt2->type) {
vt.type = vt1->type;
if (vt1->sign == ValueType::Sign::UNSIGNED || vt2->sign == ValueType::Sign::UNSIGNED)
vt.sign = ValueType::Sign::UNSIGNED;
else if (vt1->sign == ValueType::Sign::UNKNOWN_SIGN || vt2->sign == ValueType::Sign::UNKNOWN_SIGN)
vt.sign = ValueType::Sign::UNKNOWN_SIGN;
else
vt.sign = ValueType::Sign::SIGNED;
vt.originalTypeName = (vt1->originalTypeName.empty() ? vt2 : vt1)->originalTypeName;
} else if (vt1->type > vt2->type) {
vt.type = vt1->type;
vt.sign = vt1->sign;
vt.originalTypeName = vt1->originalTypeName;
} else {
vt.type = vt2->type;
vt.sign = vt2->sign;
vt.originalTypeName = vt2->originalTypeName;
}
if (vt.type < ValueType::Type::INT) {
vt.type = ValueType::Type::INT;
vt.sign = ValueType::Sign::SIGNED;
vt.originalTypeName.clear();
}
setValueType(parent, vt);
return;
}
}
@ -3864,11 +3868,18 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens)
}
// function
if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) {
else if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) {
ValueType valuetype;
if (Token::simpleMatch(parsedecl(tok->previous()->function()->retDef, &valuetype), "("))
::setValueType(tok, valuetype);
}
else if (Token::simpleMatch(tok->previous(), "sizeof (")) {
// TODO: use specified size_t type
ValueType valuetype(ValueType::Sign::UNSIGNED, ValueType::Type::LONG, 0U);
valuetype.originalTypeName = "size_t";
setValueType(tok, valuetype);
}
} else if (tok->variable()) {
setValueType(tok, *tok->variable());
}

View File

@ -1535,11 +1535,7 @@ private:
" if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n"
" ;\n"
"}");
#ifdef _MSC_VER
ASSERT_EQUALS("", errout.str());
#else
TODO_ASSERT_EQUALS("", "[test.cpp:2]: (style) Redundant condition: If 'init == 9894494448401390090', the comparison 'init == 9965707617509186058' is always true.\n", errout.str());
#endif
}
void testBug5309() {

View File

@ -2980,6 +2980,7 @@ private:
// Variable calculations
ASSERT_EQUALS("int", typeOf("int x; a = x + 1;", "+"));
ASSERT_EQUALS("int", typeOf("int x; a = x | 1;", "|"));
ASSERT_EQUALS("float", typeOf("float x; a = x + 1;", "+"));
ASSERT_EQUALS("signed int", typeOf("signed x; a = x + 1;", "x +"));
ASSERT_EQUALS("unsigned int", typeOf("unsigned x; a = x + 1;", "x +"));
@ -3013,6 +3014,7 @@ private:
// function call..
ASSERT_EQUALS("int", typeOf("int a(int); a(5);", "( 5"));
ASSERT_EQUALS("unsigned long", typeOf("sizeof(x);", "("));
}
};