Fixed #8247 (False positive knownConditionTrueFalse)
This commit is contained in:
parent
b73d4ce62e
commit
1d5e3e4f0c
|
@ -265,7 +265,7 @@ static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign
|
||||||
value.valueType = ValueFlow::Value::INT;
|
value.valueType = ValueFlow::Value::INT;
|
||||||
value.intvalue = value.floatValue;
|
value.intvalue = value.floatValue;
|
||||||
}
|
}
|
||||||
if (bit < 64) {
|
if (bit < MathLib::bigint_bits) {
|
||||||
value.intvalue &= (1ULL << bit) - 1ULL;
|
value.intvalue &= (1ULL << bit) - 1ULL;
|
||||||
if (sign == ValueType::Sign::SIGNED && value.intvalue & (1ULL << (bit - 1ULL))) {
|
if (sign == ValueType::Sign::SIGNED && value.intvalue & (1ULL << (bit - 1ULL))) {
|
||||||
value.intvalue |= ~((1ULL << bit) - 1ULL);
|
value.intvalue |= ~((1ULL << bit) - 1ULL);
|
||||||
|
@ -484,7 +484,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
result.intvalue = f ? (floatValue1 > floatValue2) : (value1->intvalue > value2->intvalue);
|
result.intvalue = f ? (floatValue1 > floatValue2) : (value1->intvalue > value2->intvalue);
|
||||||
else if (parent->str() == ">=")
|
else if (parent->str() == ">=")
|
||||||
result.intvalue = f ? (floatValue1 >= floatValue2) : (value1->intvalue >= value2->intvalue);
|
result.intvalue = f ? (floatValue1 >= floatValue2) : (value1->intvalue >= value2->intvalue);
|
||||||
else if (!f && parent->str() == ">>" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < 64)
|
else if (!f && parent->str() == ">>" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < MathLib::bigint_bits)
|
||||||
result.intvalue = value1->intvalue >> value2->intvalue;
|
result.intvalue = value1->intvalue >> value2->intvalue;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -499,7 +499,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
result.intvalue = f ? (floatValue1 < floatValue2) : (value1->intvalue < value2->intvalue);
|
result.intvalue = f ? (floatValue1 < floatValue2) : (value1->intvalue < value2->intvalue);
|
||||||
else if (parent->str() == "<=")
|
else if (parent->str() == "<=")
|
||||||
result.intvalue = f ? (floatValue1 <= floatValue2) : (value1->intvalue <= value2->intvalue);
|
result.intvalue = f ? (floatValue1 <= floatValue2) : (value1->intvalue <= value2->intvalue);
|
||||||
else if (!f && parent->str() == "<<" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < 64)
|
else if (!f && parent->str() == "<<" && value1->intvalue >= 0 && value2->intvalue >= 0 && value2->intvalue < MathLib::bigint_bits)
|
||||||
result.intvalue = value1->intvalue << value2->intvalue;
|
result.intvalue = value1->intvalue << value2->intvalue;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -569,8 +569,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
else if (tok->valueType()->type == ValueType::Type::LONG)
|
else if (tok->valueType()->type == ValueType::Type::LONG)
|
||||||
bits = settings->long_bit;
|
bits = settings->long_bit;
|
||||||
}
|
}
|
||||||
if (bits > 0 && bits < 64)
|
if (bits > 0 && bits < MathLib::bigint_bits)
|
||||||
v.intvalue &= (1ULL<<bits) - 1ULL;
|
v.intvalue &= (((MathLib::biguint)1)<<bits) - 1;
|
||||||
setTokenValue(parent, v, settings);
|
setTokenValue(parent, v, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2894,9 +2894,11 @@ static void valueFlowSwitchVariable(TokenList *tokenlist, SymbolDatabase* symbol
|
||||||
values.back().condition = tok;
|
values.back().condition = tok;
|
||||||
const std::string info("case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here.");
|
const std::string info("case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here.");
|
||||||
values.back().errorPath.push_back(ErrorPathItem(tok, info));
|
values.back().errorPath.push_back(ErrorPathItem(tok, info));
|
||||||
|
bool known = false;
|
||||||
if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case"))
|
if ((Token::simpleMatch(tok->previous(), "{") || Token::simpleMatch(tok->tokAt(-2), "break ;")) && !Token::Match(tok->tokAt(3), ";| case"))
|
||||||
values.back().setKnown();
|
known = true;
|
||||||
while (Token::Match(tok->tokAt(3), ";| case %num% :")) {
|
while (Token::Match(tok->tokAt(3), ";| case %num% :")) {
|
||||||
|
known = false;
|
||||||
tok = tok->tokAt(3);
|
tok = tok->tokAt(3);
|
||||||
if (!tok->isName())
|
if (!tok->isName())
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
@ -2914,8 +2916,11 @@ static void valueFlowSwitchVariable(TokenList *tokenlist, SymbolDatabase* symbol
|
||||||
errorLogger,
|
errorLogger,
|
||||||
settings);
|
settings);
|
||||||
}
|
}
|
||||||
if (vartok->variable()->scope()) // #7257
|
if (vartok->variable()->scope()) {
|
||||||
|
if (known)
|
||||||
|
values.back().setKnown();
|
||||||
valueFlowForward(tok->tokAt(3), vartok->variable()->scope()->classEnd, vartok->variable(), vartok->varId(), values, values.back().isKnown(), false, tokenlist, errorLogger, settings);
|
valueFlowForward(tok->tokAt(3), vartok->variable()->scope()->classEnd, vartok->variable(), vartok->varId(), values, values.back().isKnown(), false, tokenlist, errorLogger, settings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1874,7 +1874,7 @@ private:
|
||||||
void valueFlowSwitchVariable() {
|
void valueFlowSwitchVariable() {
|
||||||
const char *code;
|
const char *code;
|
||||||
code = "void f(int x) {\n"
|
code = "void f(int x) {\n"
|
||||||
" a = x;\n" // <- x can be 14
|
" a = x - 1;\n" // <- x can be 14
|
||||||
" switch (x) {\n"
|
" switch (x) {\n"
|
||||||
" case 14: a=x+2; break;\n" // <- x is 14
|
" case 14: a=x+2; break;\n" // <- x is 14
|
||||||
" };\n"
|
" };\n"
|
||||||
|
@ -1884,10 +1884,13 @@ private:
|
||||||
ASSERT_EQUALS(true, testConditionalValueOfX(code, 4U, 14));
|
ASSERT_EQUALS(true, testConditionalValueOfX(code, 4U, 14));
|
||||||
ASSERT_EQUALS(true, testConditionalValueOfX(code, 6U, 14));
|
ASSERT_EQUALS(true, testConditionalValueOfX(code, 6U, 14));
|
||||||
|
|
||||||
ValueFlow::Value value = valueOfTok(code, "+");
|
ValueFlow::Value value1 = valueOfTok(code, "-");
|
||||||
ASSERT_EQUALS(16, value.intvalue);
|
ASSERT_EQUALS(13, value1.intvalue);
|
||||||
ASSERT(value.isKnown());
|
ASSERT(!value1.isKnown());
|
||||||
|
|
||||||
|
ValueFlow::Value value2 = valueOfTok(code, "+");
|
||||||
|
ASSERT_EQUALS(16, value2.intvalue);
|
||||||
|
ASSERT(value2.isKnown());
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowForLoop() {
|
void valueFlowForLoop() {
|
||||||
|
|
Loading…
Reference in New Issue