keep type suffixes after constant folding using bit operations
This commit is contained in:
parent
4e4873772d
commit
ac8341e3de
|
@ -38,7 +38,6 @@
|
|||
#define ISNAN(x) (std::isnan(x))
|
||||
#endif
|
||||
|
||||
|
||||
MathLib::value::value(const std::string &s) :
|
||||
intValue(0), doubleValue(0), isUnsigned(false)
|
||||
{
|
||||
|
@ -263,6 +262,24 @@ MathLib::value MathLib::value::add(int v) const
|
|||
return temp;
|
||||
}
|
||||
|
||||
MathLib::value MathLib::value::shiftLeft(const MathLib::value &v) const
|
||||
{
|
||||
if (!isInt() || !v.isInt())
|
||||
throw InternalError(0, "Shift operand is not integer");
|
||||
MathLib::value ret(*this);
|
||||
ret.intValue <<= v.intValue;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MathLib::value MathLib::value::shiftRight(const MathLib::value &v) const
|
||||
{
|
||||
if (!isInt() || !v.isInt())
|
||||
throw InternalError(0, "Shift operand is not integer");
|
||||
MathLib::value ret(*this);
|
||||
ret.intValue >>= v.intValue;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
||||
{
|
||||
|
@ -1250,3 +1267,13 @@ MathLib::value operator^(const MathLib::value &v1, const MathLib::value &v2)
|
|||
{
|
||||
return MathLib::value::calc('^',v1,v2);
|
||||
}
|
||||
|
||||
MathLib::value operator<<(const MathLib::value &v1, const MathLib::value &v2)
|
||||
{
|
||||
return v1.shiftLeft(v2);
|
||||
}
|
||||
|
||||
MathLib::value operator>>(const MathLib::value &v1, const MathLib::value &v2)
|
||||
{
|
||||
return v1.shiftRight(v2);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
static value calc(char op, const value &v1, const value &v2);
|
||||
int compare(const value &v) const;
|
||||
value add(int v) const;
|
||||
value shiftLeft(const value &v) const;
|
||||
value shiftRight(const value &v) const;
|
||||
};
|
||||
|
||||
typedef long long bigint;
|
||||
|
@ -128,6 +130,8 @@ MathLib::value operator%(const MathLib::value &v1, const MathLib::value &v2);
|
|||
MathLib::value operator&(const MathLib::value &v1, const MathLib::value &v2);
|
||||
MathLib::value operator|(const MathLib::value &v1, const MathLib::value &v2);
|
||||
MathLib::value operator^(const MathLib::value &v1, const MathLib::value &v2);
|
||||
MathLib::value operator<<(const MathLib::value &v1, const MathLib::value &v2);
|
||||
MathLib::value operator>>(const MathLib::value &v1, const MathLib::value &v2);
|
||||
|
||||
template<> CPPCHECKLIB std::string MathLib::toString(double value); // Declare specialization to avoid linker problems
|
||||
|
||||
|
|
|
@ -891,48 +891,6 @@ static bool isLowerEqualThanMulDiv(const Token* lower)
|
|||
return isLowerThanMulDiv(lower) || Token::Match(lower, "[*/%]");
|
||||
}
|
||||
|
||||
static std::string ShiftInt(const char cop, const Token* left, const Token* right)
|
||||
{
|
||||
if (cop == '&' || cop == '|' || cop == '^')
|
||||
return MathLib::calculate(left->str(), right->str(), cop);
|
||||
|
||||
const MathLib::bigint leftInt = MathLib::toLongNumber(left->str());
|
||||
const MathLib::bigint rightInt = MathLib::toLongNumber(right->str());
|
||||
const bool rightIntIsPositive = rightInt >= 0;
|
||||
|
||||
if (cop == '<') {
|
||||
const bool leftOperationIsNotLeftShift = left->previous()->str() != "<<";
|
||||
const bool operandIsLeftShift = right->previous()->str() == "<<";
|
||||
|
||||
// Ensure that its not a shift operator as used for streams
|
||||
if (leftOperationIsNotLeftShift && operandIsLeftShift && rightIntIsPositive) {
|
||||
const bool leftIntIsPositive = leftInt >= 0;
|
||||
if (!leftIntIsPositive) { // In case the left integer is negative, e.g. -1000 << 16. Do not simplify.
|
||||
return left->str() + " << " + right->str();
|
||||
}
|
||||
return MathLib::toString(leftInt << rightInt);
|
||||
}
|
||||
} else if (rightIntIsPositive) {
|
||||
return MathLib::toString(leftInt >> rightInt);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string ShiftUInt(const char cop, const Token* left, const Token* right)
|
||||
{
|
||||
if (cop == '&' || cop == '|' || cop == '^')
|
||||
return MathLib::calculate(left->str(), right->str(), cop);
|
||||
|
||||
const MathLib::biguint leftInt=MathLib::toULongNumber(left->str());
|
||||
const MathLib::biguint rightInt=MathLib::toULongNumber(right->str());
|
||||
if (cop == '<') {
|
||||
if (left->previous()->str() != "<<") // Ensure that its not a shift operator as used for streams
|
||||
return MathLib::toString(leftInt << rightInt);
|
||||
} else {
|
||||
return MathLib::toString(leftInt >> rightInt);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool TemplateSimplifier::simplifyNumericCalculations(Token *tok)
|
||||
{
|
||||
|
@ -968,15 +926,34 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok)
|
|||
if (MathLib::isNegative(tok->str()) || MathLib::isNegative(tok->strAt(2)))
|
||||
continue;
|
||||
|
||||
const char cop = op->str()[0];
|
||||
std::string result;
|
||||
if (tok->str().find_first_of("uU") != std::string::npos)
|
||||
result = ShiftUInt(cop, tok, tok->tokAt(2));
|
||||
else
|
||||
result = ShiftInt(cop, tok, tok->tokAt(2));
|
||||
if (result.empty())
|
||||
const MathLib::value v1(tok->str());
|
||||
const MathLib::value v2(tok->strAt(2));
|
||||
|
||||
if (!v1.isInt() || !v2.isInt())
|
||||
continue;
|
||||
|
||||
switch (op->str()[0]) {
|
||||
case '<':
|
||||
tok->str((v1 << v2).str());
|
||||
ret = true;
|
||||
break;
|
||||
tok->str(result);
|
||||
case '>':
|
||||
tok->str((v1 >> v2).str());
|
||||
ret = true;
|
||||
break;
|
||||
case '&':
|
||||
tok->str((v1 & v2).str());
|
||||
ret = true;
|
||||
break;
|
||||
case '|':
|
||||
tok->str((v1 | v2).str());
|
||||
ret = true;
|
||||
break;
|
||||
case '^':
|
||||
tok->str((v1 ^ v2).str());
|
||||
ret = true;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// Logical operations
|
||||
|
|
|
@ -2650,8 +2650,8 @@ private:
|
|||
}
|
||||
|
||||
void simplifyKnownVariables57() { // #4724
|
||||
ASSERT_EQUALS("unsigned long long x ; x = 9223372036854775808 ;", tokenizeAndStringify("unsigned long long x = 1UL << 63 ;", true));
|
||||
ASSERT_EQUALS("long long x ; x = -9223372036854775808 ;", tokenizeAndStringify("long long x = 1L << 63 ;", true));
|
||||
ASSERT_EQUALS("unsigned long long x ; x = 9223372036854775808UL ;", tokenizeAndStringify("unsigned long long x = 1UL << 63 ;", true));
|
||||
ASSERT_EQUALS("long long x ; x = -9223372036854775808L ;", tokenizeAndStringify("long long x = 1L << 63 ;", true));
|
||||
}
|
||||
|
||||
void simplifyKnownVariables58() { // #5268
|
||||
|
|
Loading…
Reference in New Issue