Fixed #9032 (False-positive detection of reassigned value before used for pointer parameter)
This commit is contained in:
parent
d82c792c1b
commit
418eb43d45
|
@ -1122,9 +1122,9 @@ bool isConstVarExpression(const Token *tok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nonLocal(const Variable* var)
|
static bool nonLocal(const Variable* var, bool deref)
|
||||||
{
|
{
|
||||||
return !var || (!var->isLocal() && !var->isArgument()) || var->isStatic() || var->isReference() || var->isExtern();
|
return !var || (!var->isLocal() && !var->isArgument()) || (deref && var->isArgument() && var->isPointer()) || var->isStatic() || var->isReference() || var->isExtern();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasFunctionCall(const Token *tok)
|
static bool hasFunctionCall(const Token *tok)
|
||||||
|
@ -1175,6 +1175,9 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
|
||||||
return Result(Result::Type::READ);
|
return Result(Result::Type::READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!local && mWhat == What::Reassign)
|
||||||
|
return Result(Result::Type::BAILOUT);
|
||||||
|
|
||||||
return Result(Result::Type::RETURN);
|
return Result(Result::Type::RETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,7 +1394,8 @@ FwdAnalysis::Result FwdAnalysis::check(const Token *expr, const Token *startToke
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
if (var && var->isReference() && var->isLocal() && Token::Match(var->nameToken(), "%var% [=(]") && !isGlobalData(var->nameToken()->next()->astOperand2()))
|
if (var && var->isReference() && var->isLocal() && Token::Match(var->nameToken(), "%var% [=(]") && !isGlobalData(var->nameToken()->next()->astOperand2()))
|
||||||
return ChildrenToVisit::none;
|
return ChildrenToVisit::none;
|
||||||
local &= !nonLocal(tok->variable());
|
const bool deref = tok->astParent() && (tok->astParent()->isUnaryOp("*") || (tok->astParent()->str() == "[" && tok == tok->astParent()->astOperand1()));
|
||||||
|
local &= !nonLocal(tok->variable(), deref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ChildrenToVisit::op1_and_op2;
|
return ChildrenToVisit::op1_and_op2;
|
||||||
|
|
|
@ -166,6 +166,7 @@ private:
|
||||||
TEST_CASE(redundantVarAssignment_lambda);
|
TEST_CASE(redundantVarAssignment_lambda);
|
||||||
TEST_CASE(redundantVarAssignment_for);
|
TEST_CASE(redundantVarAssignment_for);
|
||||||
TEST_CASE(redundantVarAssignment_after_switch);
|
TEST_CASE(redundantVarAssignment_after_switch);
|
||||||
|
TEST_CASE(redundantVarAssignment_pointer_parameter);
|
||||||
TEST_CASE(redundantMemWrite);
|
TEST_CASE(redundantMemWrite);
|
||||||
|
|
||||||
TEST_CASE(varFuncNullUB);
|
TEST_CASE(varFuncNullUB);
|
||||||
|
@ -6105,6 +6106,15 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:8]: (style) Variable 'ret' is reassigned a value before the old one has been used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:8]: (style) Variable 'ret' is reassigned a value before the old one has been used.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void redundantVarAssignment_pointer_parameter() {
|
||||||
|
check("void f(int *p) {\n"
|
||||||
|
" *p = 1;\n"
|
||||||
|
" if (condition) return;\n"
|
||||||
|
" *p = 2;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void redundantMemWrite() {
|
void redundantMemWrite() {
|
||||||
return; // FIXME: temporary hack
|
return; // FIXME: temporary hack
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue