Fix 10323: Wrong known value. x!=0 does not mean that x==1 (#3308)

This commit is contained in:
Paul Fultz II 2021-06-26 02:16:45 -05:00 committed by GitHub
parent 508188df2b
commit 66956ed959
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 6 deletions

View File

@ -4014,6 +4014,7 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
const Token* condTok = parenTok->astOperand2();
if (condTok->hasKnownIntValue())
continue;
const bool is1 = (condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp || astIsBool(condTok));
Token* startTok = blockTok;
// Inner condition
@ -4024,8 +4025,10 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
conds.insert(conds.end(), args.begin(), args.end());
}
for (const Token* condTok2:conds) {
if (is1) {
ExpressionAnalyzer a1(condTok2, makeConditionValue(1, condTok2, true), tokenlist);
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
}
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(0, condTok2, true), tokenlist);
valueFlowGenericForward(startTok, startTok->link(), a2, settings);
@ -4045,10 +4048,12 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
if (is1) {
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist);
valueFlowGenericForward(startTok, startTok->link(), a2, settings);
}
}
}
// Check if the block terminates early
if (isEscapeScope(blockTok, tokenlist)) {
@ -4056,10 +4061,12 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
valueFlowGenericForward(startTok->link()->next(), scope->bodyEnd, a1, settings);
if (is1) {
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist);
valueFlowGenericForward(startTok->link()->next(), scope->bodyEnd, a2, settings);
}
}
}
}
}

View File

@ -3633,6 +3633,20 @@ private:
"}\n");
ASSERT_EQUALS("", errout.str());
// #10323
check("void foo(int x) {\n"
" if(x)\n"
" if(x == 1) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void foo(int x) {\n"
" if(x) {}\n"
" else\n"
" if(x == 1) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'x==1' is always false\n", errout.str());
// do not report both unsignedLessThanZero and knownConditionTrueFalse
check("void foo(unsigned int max) {\n"
" unsigned int num = max - 1;\n"