5355: False postive var not assigned
Avoid false positive "variable not assigned" for struct Fred{ }; void foo () { Fred fred; throw fred; } Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
b3bfd5014d
commit
6bfd4af5f7
|
@ -1126,7 +1126,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
|
|||
unreadVariableError(usage._lastAccess, varname);
|
||||
|
||||
// variable has been read but not written
|
||||
else if (!usage._write && !usage._allocateMemory && !var->isStlType())
|
||||
else if (!usage._write && !usage._allocateMemory && !var->isStlType() && !isEmptyType(var->type()))
|
||||
unassignedVariableError(usage._var->nameToken(), varname);
|
||||
}
|
||||
}
|
||||
|
@ -1291,3 +1291,29 @@ bool CheckUnusedVar::isRecordTypeWithoutSideEffects(const Type* type)
|
|||
withoutSideEffects=false; // unknown types are assumed to have side effects
|
||||
return withoutSideEffects;
|
||||
}
|
||||
|
||||
bool CheckUnusedVar::isEmptyType(const Type* type)
|
||||
{
|
||||
// a type that has no variables and no constructor
|
||||
|
||||
std::pair<std::map<const Type *,bool>::iterator,bool> found=isEmptyTypeMap.insert(
|
||||
std::pair<const Type *,bool>(type,false));
|
||||
bool & emptyType=found.first->second;
|
||||
if (!found.second)
|
||||
return emptyType;
|
||||
|
||||
if (type && type->classScope && type->classScope->numConstructors == 0 &&
|
||||
(type->classScope->varlist.empty())) {
|
||||
for (std::vector<Type::BaseInfo>::const_iterator i = type->derivedFrom.begin(); i != type->derivedFrom.end(); ++i) {
|
||||
if (!isEmptyType(i->type)) {
|
||||
emptyType=false;
|
||||
return emptyType;
|
||||
}
|
||||
}
|
||||
emptyType=true;
|
||||
return emptyType;
|
||||
}
|
||||
|
||||
emptyType=false; // unknown types are assumed to be nonempty
|
||||
return emptyType;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
|
||||
private:
|
||||
bool isRecordTypeWithoutSideEffects(const Type* type);
|
||||
bool isEmptyType(const Type* type);
|
||||
|
||||
// Error messages..
|
||||
void unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname);
|
||||
|
@ -110,6 +111,9 @@ private:
|
|||
}
|
||||
|
||||
std::map<const Type *,bool> isRecordTypeWithoutSideEffectsMap;
|
||||
|
||||
std::map<const Type *,bool> isEmptyTypeMap;
|
||||
|
||||
};
|
||||
/// @}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -34,6 +34,9 @@ public:
|
|||
|
||||
private:
|
||||
void run() {
|
||||
TEST_CASE(emptyclass); // #5355 - False positive: Variable is not assigned a value.
|
||||
TEST_CASE(emptystruct); // #5355 - False positive: Variable is not assigned a value.
|
||||
|
||||
TEST_CASE(structmember1);
|
||||
TEST_CASE(structmember2);
|
||||
TEST_CASE(structmember3);
|
||||
|
@ -175,6 +178,30 @@ private:
|
|||
checkUnusedVar.checkStructMemberUsage();
|
||||
}
|
||||
|
||||
// #5355 - False positive: Variable is not assigned a value.
|
||||
void emptyclass() {
|
||||
functionVariableUsage("class Carla {\n"
|
||||
"};\n"
|
||||
"class Fred : Carla {\n"
|
||||
"};\n"
|
||||
"void foo() {\n"
|
||||
" Fred fred;\n"
|
||||
" throw fred;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// #5355 - False positive: Variable is not assigned a value.
|
||||
void emptystruct() {
|
||||
functionVariableUsage("struct Fred {\n"
|
||||
"};\n"
|
||||
"void foo() {\n"
|
||||
" Fred fred;\n"
|
||||
" throw fred;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void structmember1() {
|
||||
checkStructMemberUsage("struct abc\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue