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);
|
unreadVariableError(usage._lastAccess, varname);
|
||||||
|
|
||||||
// variable has been read but not written
|
// 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);
|
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
|
withoutSideEffects=false; // unknown types are assumed to have side effects
|
||||||
return withoutSideEffects;
|
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:
|
private:
|
||||||
bool isRecordTypeWithoutSideEffects(const Type* type);
|
bool isRecordTypeWithoutSideEffects(const Type* type);
|
||||||
|
bool isEmptyType(const Type* type);
|
||||||
|
|
||||||
// Error messages..
|
// Error messages..
|
||||||
void unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname);
|
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> isRecordTypeWithoutSideEffectsMap;
|
||||||
|
|
||||||
|
std::map<const Type *,bool> isEmptyTypeMap;
|
||||||
|
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -34,6 +34,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run() {
|
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(structmember1);
|
||||||
TEST_CASE(structmember2);
|
TEST_CASE(structmember2);
|
||||||
TEST_CASE(structmember3);
|
TEST_CASE(structmember3);
|
||||||
|
@ -175,6 +178,30 @@ private:
|
||||||
checkUnusedVar.checkStructMemberUsage();
|
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() {
|
void structmember1() {
|
||||||
checkStructMemberUsage("struct abc\n"
|
checkStructMemberUsage("struct abc\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue