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

View File

@ -924,17 +924,19 @@ private:
" int x = 0;\n"
" x = x & 0x1;\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(true, testValueOfX(code, 5U, 2));
code = "void f() {\n" // #6118 - FN
" int x = 0;\n"
" x = x & 0x1;\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"
" struct ABC *x;\n"
@ -1311,6 +1313,13 @@ private:
"}";
ASSERT_EQUALS(false, testValueOfX(code,3U,0));
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() {