Fix #10792 FP knownConditionTrueFalse with double to int cast (#3964)

This commit is contained in:
chrchr-github 2022-04-07 10:42:57 +02:00 committed by GitHub
parent dad10f2ab7
commit 52b4aeb279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 2 deletions

View File

@ -949,6 +949,9 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
return tok; return tok;
if (isStructuredBindingVariable(var)) if (isStructuredBindingVariable(var))
return tok; return tok;
// assigning a floating point value to an integer does not preserve the value
if (var->valueType() && var->valueType()->isIntegral() && varTok->valueType() && varTok->valueType()->isFloat())
return tok;
const Token * lastTok = precedes(tok, end) ? end : tok; const Token * lastTok = precedes(tok, end) ? end : tok;
// If this is in a loop then check if variables are modified in the entire scope // If this is in a loop then check if variables are modified in the entire scope
const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok;

View File

@ -253,12 +253,12 @@ const Token *parseCompareInt(const Token *tok, ValueFlow::Value &true_value, Val
value1.clear(); value1.clear();
} }
if (!value1.empty()) { if (!value1.empty()) {
if (isSaturated(value1.front())) if (isSaturated(value1.front()) || astIsFloat(tok->astOperand2(), /*unknown*/ false))
return nullptr; return nullptr;
setConditionalValues(tok, true, value1.front(), true_value, false_value); setConditionalValues(tok, true, value1.front(), true_value, false_value);
return tok->astOperand2(); return tok->astOperand2();
} else if (!value2.empty()) { } else if (!value2.empty()) {
if (isSaturated(value2.front())) if (isSaturated(value2.front()) || astIsFloat(tok->astOperand1(), /*unknown*/ false))
return nullptr; return nullptr;
setConditionalValues(tok, false, value2.front(), true_value, false_value); setConditionalValues(tok, false, value2.front(), true_value, false_value);
return tok->astOperand1(); return tok->astOperand1();

View File

@ -2491,6 +2491,14 @@ private:
" if (!b && f()) {}\n" " if (!b && f()) {}\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(double d) {\n"
" if (d != 0) {\n"
" int i = d;\n"
" if (i == 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void identicalInnerCondition() { void identicalInnerCondition() {
@ -4018,6 +4026,31 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'w' is always true\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'w' is always true\n", errout.str());
check("void f(double d) {\n" // #10792
" if (d != 0) {\n"
" int i = (int)d;\n"
" if (i == 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f(double d) {\n"
" if (0 != d) {\n"
" int i = (int)d;\n"
" if (i == 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct A { double d; }\n"
"void f(A a) {\n"
" if (a.d != 0) {\n"
" int i = a.d;\n"
" if (i == 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"
" if(strlen(\"abc\") == 3) {;}\n" " if(strlen(\"abc\") == 3) {;}\n"
" if(strlen(\"abc\") == 1) {;}\n" " if(strlen(\"abc\") == 1) {;}\n"