Fixed #3747 (False 'boolean result in bitwise' message with 'mask' enums)

This commit is contained in:
Daniel Marjamäki 2012-05-16 18:48:33 +02:00
parent c976325086
commit 0bb0fdedc2
4 changed files with 43 additions and 6 deletions

View File

@ -251,6 +251,15 @@ std::string MathLib::calculate(const std::string &first, const std::string &seco
case '%': case '%':
return MathLib::mod(first, second); 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: default:
throw InternalError(0, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers."); throw InternalError(0, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers.");
} }

View File

@ -897,12 +897,8 @@ bool TemplateSimplifier::simplifyCalculations(Token *_tokens)
const MathLib::bigint rightInt(MathLib::toLongNumber(tok->strAt(2))); const MathLib::bigint rightInt(MathLib::toLongNumber(tok->strAt(2)));
std::string result; std::string result;
if (cop == '&') if (cop == '&' || cop == '|' || cop == '^')
result = MathLib::toString<MathLib::bigint>(leftInt & rightInt); result = MathLib::calculate(tok->str(), tok->strAt(2), cop);
else if (cop == '|')
result = MathLib::toString<MathLib::bigint>(leftInt | rightInt);
else if (cop == '^')
result = MathLib::toString<MathLib::bigint>(leftInt ^ rightInt);
else if (cop == '<') { else if (cop == '<') {
if (tok->previous()->str() != "<<") // Ensure that its not a shift operator as used for streams if (tok->previous()->str() != "<<") // Ensure that its not a shift operator as used for streams
result = MathLib::toString<MathLib::bigint>(leftInt << rightInt); result = MathLib::toString<MathLib::bigint>(leftInt << rightInt);

View File

@ -7008,6 +7008,32 @@ void Tokenizer::simplifyEnum()
} }
if (simplify) { 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) if (enumValue)
tok2->str(enumValue->str()); tok2->str(enumValue->str());
else { else {

View File

@ -344,6 +344,7 @@ private:
TEST_CASE(enum26); // ticket #2975 (segmentation fault) TEST_CASE(enum26); // ticket #2975 (segmentation fault)
TEST_CASE(enum27); // ticket #3005 (segmentation fault) TEST_CASE(enum27); // ticket #3005 (segmentation fault)
TEST_CASE(enum28); TEST_CASE(enum28);
TEST_CASE(enum29); // ticket #3747 (bitwise or value)
// remove "std::" on some standard functions // remove "std::" on some standard functions
TEST_CASE(removestd); 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)); 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() { void removestd() {
ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);")); ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);"));
ASSERT_EQUALS("; strcat ( a , b ) ;", tok("; std::strcat(a,b);")); ASSERT_EQUALS("; strcat ( a , b ) ;", tok("; std::strcat(a,b);"));