Fixed #7039 (ValueFlow: bitand calculation '16&15')

This commit is contained in:
Daniel Marjamäki 2015-10-14 10:44:04 +02:00
parent a04e072976
commit 60f8982999
2 changed files with 25 additions and 4 deletions

View File

@ -449,7 +449,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
} }
// Calculations.. // Calculations..
else if ((parent->isArithmeticalOp() || parent->isComparisonOp()) && else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp)) &&
parent->astOperand1() && parent->astOperand1() &&
parent->astOperand2()) { parent->astOperand2()) {
const bool known = ((parent->astOperand1()->values.size() == 1U && const bool known = ((parent->astOperand1()->values.size() == 1U &&
@ -537,6 +537,18 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
break; break;
setTokenValue(parent, result); setTokenValue(parent, result);
break; break;
case '&':
result.intvalue = value1->intvalue & value2->intvalue;
setTokenValue(parent, result);
break;
case '|':
result.intvalue = value1->intvalue | value2->intvalue;
setTokenValue(parent, result);
break;
case '^':
result.intvalue = value1->intvalue ^ value2->intvalue;
setTokenValue(parent, result);
break;
default: default:
// unhandled operator, do nothing // unhandled operator, do nothing
break; break;

View File

@ -924,17 +924,19 @@ private:
" int x = 0;\n" " int x = 0;\n"
" x = x & 0x1;\n" " x = x & 0x1;\n"
" if (x == 0) { x = 2; }\n" " if (x == 0) { x = 2; }\n"
" y = 42 / x;\n" // <- x can't be 0 " y = 42 / x;\n" // <- x is 2
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 5U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 5U, 0));
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2));
code = "void f() {\n" // #6118 - FN code = "void f() {\n" // #6118 - FN
" int x = 0;\n" " int x = 0;\n"
" x = x & 0x1;\n" " x = x & 0x1;\n"
" if (x == 0) { x += 2; }\n" " if (x == 0) { x += 2; }\n"
" y = 42 / x;\n" // <- x can be 2 " y = 42 / x;\n" // <- x is 2
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2)); ASSERT_EQUALS(false, testValueOfX(code, 5U, 0));
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 5U, 2));
code = "void f(int mode) {\n" code = "void f(int mode) {\n"
" struct ABC *x;\n" " struct ABC *x;\n"
@ -1311,6 +1313,13 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code,3U,0)); ASSERT_EQUALS(false, testValueOfX(code,3U,0));
ASSERT_EQUALS(false, testValueOfX(code,3U,0x80)); ASSERT_EQUALS(false, testValueOfX(code,3U,0x80));
code = "int f() {\n"
" int x = (19 - 3) & 15;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code,3U,0));
ASSERT_EQUALS(false, testValueOfX(code,3U,16));
} }
void valueFlowSwitchVariable() { void valueFlowSwitchVariable() {