Fixed #3747 (False 'boolean result in bitwise' message with 'mask' enums)
This commit is contained in:
parent
c976325086
commit
0bb0fdedc2
|
@ -251,6 +251,15 @@ std::string MathLib::calculate(const std::string &first, const std::string &seco
|
|||
case '%':
|
||||
return MathLib::mod(first, second);
|
||||
|
||||
case '&':
|
||||
return MathLib::toString(MathLib::toLongNumber(first) & MathLib::toLongNumber(second));
|
||||
|
||||
case '|':
|
||||
return MathLib::toString(MathLib::toLongNumber(first) | MathLib::toLongNumber(second));
|
||||
|
||||
case '^':
|
||||
return MathLib::toString(MathLib::toLongNumber(first) ^ MathLib::toLongNumber(second));
|
||||
|
||||
default:
|
||||
throw InternalError(0, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers.");
|
||||
}
|
||||
|
|
|
@ -897,12 +897,8 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
|
|||
const MathLib::bigint rightInt(MathLib::toLongNumber(tok->strAt(2)));
|
||||
std::string result;
|
||||
|
||||
if (cop == '&')
|
||||
result = MathLib::toString<MathLib::bigint>(leftInt & rightInt);
|
||||
else if (cop == '|')
|
||||
result = MathLib::toString<MathLib::bigint>(leftInt | rightInt);
|
||||
else if (cop == '^')
|
||||
result = MathLib::toString<MathLib::bigint>(leftInt ^ rightInt);
|
||||
if (cop == '&' || cop == '|' || cop == '^')
|
||||
result = MathLib::calculate(tok->str(), tok->strAt(2), cop);
|
||||
else if (cop == '<') {
|
||||
if (tok->previous()->str() != "<<") // Ensure that its not a shift operator as used for streams
|
||||
result = MathLib::toString<MathLib::bigint>(leftInt << rightInt);
|
||||
|
|
|
@ -7008,6 +7008,32 @@ void Tokenizer::simplifyEnum()
|
|||
}
|
||||
|
||||
if (simplify) {
|
||||
// Simplify calculations..
|
||||
while (Token::Match(enumValueStart, "%num% %op% %num% %op%") &&
|
||||
enumValueStart->strAt(1) == enumValueStart->strAt(3)) {
|
||||
const std::string &op = enumValueStart->strAt(1);
|
||||
if (op.size() != 1U)
|
||||
break;
|
||||
const std::string &val1 = enumValueStart->str();
|
||||
const std::string &val2 = enumValueStart->strAt(2);
|
||||
const std::string result = MathLib::calculate(val1, val2, op[0]);
|
||||
enumValueStart->str(result);
|
||||
enumValueStart->deleteNext(2);
|
||||
}
|
||||
if (Token::Match(enumValueStart, "%num% %op% %num% [,}]")) {
|
||||
const std::string &op = enumValueStart->strAt(1);
|
||||
if (op.size() == 1U) {
|
||||
const std::string &val1 = enumValueStart->str();
|
||||
const std::string &val2 = enumValueStart->strAt(2);
|
||||
const std::string result = MathLib::calculate(val1, val2, op[0]);
|
||||
enumValueStart->str(result);
|
||||
enumValueStart->deleteNext(2);
|
||||
enumValue = enumValueStart;
|
||||
enumValueStart = enumValueEnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (enumValue)
|
||||
tok2->str(enumValue->str());
|
||||
else {
|
||||
|
|
|
@ -344,6 +344,7 @@ private:
|
|||
TEST_CASE(enum26); // ticket #2975 (segmentation fault)
|
||||
TEST_CASE(enum27); // ticket #3005 (segmentation fault)
|
||||
TEST_CASE(enum28);
|
||||
TEST_CASE(enum29); // ticket #3747 (bitwise or value)
|
||||
|
||||
// remove "std::" on some standard functions
|
||||
TEST_CASE(removestd);
|
||||
|
@ -6985,6 +6986,11 @@ private:
|
|||
ASSERT_EQUALS("void f ( ) { char x [ 4 ] ; memset ( x , 0 , 4 ) ; { x } } ; void g ( ) { 0 ; }", checkSimplifyEnum(code));
|
||||
}
|
||||
|
||||
void enum29() { // #3747 - bitwise or value
|
||||
const char code[] = "enum { x=1, y=x|2 }; i = (3==y);";
|
||||
ASSERT_EQUALS("i = 3 == 3 ;", checkSimplifyEnum(code));
|
||||
}
|
||||
|
||||
void removestd() {
|
||||
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));
|
||||
ASSERT_EQUALS("; strcat ( a , b ) ;", tok("; std::strcat(a,b);"));
|
||||
|
|
Loading…
Reference in New Issue