diff --git a/lib/astutils.cpp b/lib/astutils.cpp index d7360b72f..e51433dca 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 298f67c08..c4c1dc341 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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()); } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index efccd3eea..e0e16a333 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -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() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index bf44ebe73..07bf1ed93 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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);", "(")); } };