Fixed false negative in unused variable checking when class without side effects inherits from another one.
This commit is contained in:
parent
c7e2490f2b
commit
c537a86363
|
@ -537,16 +537,17 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
|
|||
return tok;
|
||||
}
|
||||
|
||||
static bool isRecordTypeWithoutSideEffects(const Variable& var)
|
||||
static bool isRecordTypeWithoutSideEffects(const Scope* type)
|
||||
{
|
||||
// a type that has no side effects (no constructors and no members with constructors)
|
||||
/** @todo false negative: check base class for side effects */
|
||||
/** @todo false negative: check constructors for side effects */
|
||||
if (var.type() && var.type()->numConstructors == 0 &&
|
||||
(var.type()->varlist.empty() || var.type()->needInitialization == Scope::True) &&
|
||||
var.type()->derivedFrom.empty())
|
||||
return true;
|
||||
|
||||
if (type && type->numConstructors == 0 &&
|
||||
(type->varlist.empty() || type->needInitialization == Scope::True)) {
|
||||
bool yes = true;
|
||||
for (std::vector<Scope::BaseInfo>::const_iterator i = type->derivedFrom.begin(); yes && i != type->derivedFrom.end(); ++i)
|
||||
yes = isRecordTypeWithoutSideEffects(i->scope);
|
||||
return yes;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -612,7 +613,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
type = Variables::pointerPointer;
|
||||
else if (i->isPointer())
|
||||
type = Variables::pointer;
|
||||
else if (_tokenizer->isC() || i->typeEndToken()->isStandardType() || isRecordTypeWithoutSideEffects(*i) || Token::simpleMatch(i->typeStartToken(), "std ::"))
|
||||
else if (_tokenizer->isC() || i->typeEndToken()->isStandardType() || isRecordTypeWithoutSideEffects(i->type()) || Token::simpleMatch(i->typeStartToken(), "std ::"))
|
||||
type = Variables::standard;
|
||||
if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken()))
|
||||
continue;
|
||||
|
@ -787,7 +788,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
// is it a user defined type?
|
||||
if (!type->isStandardType()) {
|
||||
const Variable* variable = _tokenizer->getSymbolDatabase()->getVariableFromVarId(start->varId());
|
||||
if (!variable || !isRecordTypeWithoutSideEffects(*variable))
|
||||
if (!variable || !isRecordTypeWithoutSideEffects(variable->type()))
|
||||
allocate = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2580,6 +2580,14 @@ private:
|
|||
" return 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
functionVariableUsage("class Fred {char c;};\n"
|
||||
"class A : public Fred { int i; };\n"
|
||||
"int foo() {\n"
|
||||
" A a;\n"
|
||||
" return 0;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n", errout.str());
|
||||
}
|
||||
|
||||
void localvarStruct6() {
|
||||
|
|
Loading…
Reference in New Issue