ValueType: Handle bit operations, sizeof better. Use ValueType in astIsFloat().
This commit is contained in:
parent
5b082aa799
commit
ac9cb87e04
|
@ -71,43 +71,10 @@ bool astIsIntegral(const Token *tok, bool unknown)
|
||||||
|
|
||||||
bool astIsFloat(const Token *tok, bool unknown)
|
bool astIsFloat(const Token *tok, bool unknown)
|
||||||
{
|
{
|
||||||
// TODO: handle arrays
|
const ValueType *vt = tok ? tok->valueType() : nullptr;
|
||||||
if (tok->isNumber())
|
if (!vt)
|
||||||
return MathLib::isFloat(tok->str());
|
|
||||||
|
|
||||||
if (tok->isName()) {
|
|
||||||
if (tok->variable())
|
|
||||||
return tok->variable()->isFloatingType();
|
|
||||||
|
|
||||||
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 unknown;
|
||||||
|
return vt->type >= ValueType::Type::FLOAT && vt->pointer == 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string astCanonicalType(const Token *expr)
|
std::string astCanonicalType(const Token *expr)
|
||||||
|
|
|
@ -3744,37 +3744,41 @@ static void setValueType(Token *tok, const ValueType &valuetype)
|
||||||
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U));
|
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U));
|
||||||
return;
|
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));
|
if (vt2 &&
|
||||||
return;
|
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
|
// function
|
||||||
if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) {
|
else if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) {
|
||||||
ValueType valuetype;
|
ValueType valuetype;
|
||||||
if (Token::simpleMatch(parsedecl(tok->previous()->function()->retDef, &valuetype), "("))
|
if (Token::simpleMatch(parsedecl(tok->previous()->function()->retDef, &valuetype), "("))
|
||||||
::setValueType(tok, 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()) {
|
} else if (tok->variable()) {
|
||||||
setValueType(tok, *tok->variable());
|
setValueType(tok, *tok->variable());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1535,11 +1535,7 @@ private:
|
||||||
" if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n"
|
" if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n"
|
||||||
" ;\n"
|
" ;\n"
|
||||||
"}");
|
"}");
|
||||||
#ifdef _MSC_VER
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void testBug5309() {
|
||||||
|
|
|
@ -2980,6 +2980,7 @@ private:
|
||||||
|
|
||||||
// Variable calculations
|
// Variable calculations
|
||||||
ASSERT_EQUALS("int", typeOf("int x; a = x + 1;", "+"));
|
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("float", typeOf("float x; a = x + 1;", "+"));
|
||||||
ASSERT_EQUALS("signed int", typeOf("signed x; a = x + 1;", "x +"));
|
ASSERT_EQUALS("signed int", typeOf("signed x; a = x + 1;", "x +"));
|
||||||
ASSERT_EQUALS("unsigned int", typeOf("unsigned x; a = x + 1;", "x +"));
|
ASSERT_EQUALS("unsigned int", typeOf("unsigned x; a = x + 1;", "x +"));
|
||||||
|
@ -3013,6 +3014,7 @@ private:
|
||||||
|
|
||||||
// function call..
|
// function call..
|
||||||
ASSERT_EQUALS("int", typeOf("int a(int); a(5);", "( 5"));
|
ASSERT_EQUALS("int", typeOf("int a(int); a(5);", "( 5"));
|
||||||
|
ASSERT_EQUALS("unsigned long", typeOf("sizeof(x);", "("));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue