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))
|
#define ISNAN(x) (std::isnan(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
MathLib::value::value(const std::string &s) :
|
MathLib::value::value(const std::string &s) :
|
||||||
intValue(0), doubleValue(0), isUnsigned(false)
|
intValue(0), doubleValue(0), isUnsigned(false)
|
||||||
{
|
{
|
||||||
|
@ -263,6 +262,24 @@ MathLib::value MathLib::value::add(int v) const
|
||||||
return temp;
|
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)
|
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);
|
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);
|
static value calc(char op, const value &v1, const value &v2);
|
||||||
int compare(const value &v) const;
|
int compare(const value &v) const;
|
||||||
value add(int v) const;
|
value add(int v) const;
|
||||||
|
value shiftLeft(const value &v) const;
|
||||||
|
value shiftRight(const value &v) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef long long bigint;
|
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);
|
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
|
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, "[*/%]");
|
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)
|
bool TemplateSimplifier::simplifyNumericCalculations(Token *tok)
|
||||||
{
|
{
|
||||||
|
@ -968,15 +926,34 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok)
|
||||||
if (MathLib::isNegative(tok->str()) || MathLib::isNegative(tok->strAt(2)))
|
if (MathLib::isNegative(tok->str()) || MathLib::isNegative(tok->strAt(2)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char cop = op->str()[0];
|
const MathLib::value v1(tok->str());
|
||||||
std::string result;
|
const MathLib::value v2(tok->strAt(2));
|
||||||
if (tok->str().find_first_of("uU") != std::string::npos)
|
|
||||||
result = ShiftUInt(cop, tok, tok->tokAt(2));
|
if (!v1.isInt() || !v2.isInt())
|
||||||
else
|
continue;
|
||||||
result = ShiftInt(cop, tok, tok->tokAt(2));
|
|
||||||
if (result.empty())
|
switch (op->str()[0]) {
|
||||||
|
case '<':
|
||||||
|
tok->str((v1 << v2).str());
|
||||||
|
ret = true;
|
||||||
break;
|
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
|
// Logical operations
|
||||||
|
|
|
@ -2650,8 +2650,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyKnownVariables57() { // #4724
|
void simplifyKnownVariables57() { // #4724
|
||||||
ASSERT_EQUALS("unsigned long long x ; x = 9223372036854775808 ;", tokenizeAndStringify("unsigned long long x = 1UL << 63 ;", true));
|
ASSERT_EQUALS("unsigned long long x ; x = 9223372036854775808UL ;", tokenizeAndStringify("unsigned long long x = 1UL << 63 ;", true));
|
||||||
ASSERT_EQUALS("long long x ; x = -9223372036854775808 ;", tokenizeAndStringify("long long x = 1L << 63 ;", true));
|
ASSERT_EQUALS("long long x ; x = -9223372036854775808L ;", tokenizeAndStringify("long long x = 1L << 63 ;", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyKnownVariables58() { // #5268
|
void simplifyKnownVariables58() { // #5268
|
||||||
|
|
Loading…
Reference in New Issue