Checking in fix for issue 9957 - - False negative: duplInheritedMember (#2964)
This commit is contained in:
parent
69f5a0df72
commit
7d6fc23022
|
@ -2439,22 +2439,28 @@ void CheckClass::checkDuplInheritedMembers()
|
||||||
// Iterate over all classes
|
// Iterate over all classes
|
||||||
for (const Type &classIt : mSymbolDatabase->typeList) {
|
for (const Type &classIt : mSymbolDatabase->typeList) {
|
||||||
// Iterate over the parent classes
|
// Iterate over the parent classes
|
||||||
for (const Type::BaseInfo &parentClassIt : classIt.derivedFrom) {
|
checkDuplInheritedMembersRecursive(&classIt, &classIt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckClass::checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase)
|
||||||
|
{
|
||||||
|
for (const Type::BaseInfo &parentClassIt : typeBase->derivedFrom) {
|
||||||
// Check if there is info about the 'Base' class
|
// Check if there is info about the 'Base' class
|
||||||
if (!parentClassIt.type || !parentClassIt.type->classScope)
|
if (!parentClassIt.type || !parentClassIt.type->classScope)
|
||||||
continue;
|
continue;
|
||||||
// Check if they have a member variable in common
|
// Check if they have a member variable in common
|
||||||
for (const Variable &classVarIt : classIt.classScope->varlist) {
|
for (const Variable &classVarIt : typeCurrent->classScope->varlist) {
|
||||||
for (const Variable &parentClassVarIt : parentClassIt.type->classScope->varlist) {
|
for (const Variable &parentClassVarIt : parentClassIt.type->classScope->varlist) {
|
||||||
if (classVarIt.name() == parentClassVarIt.name() && !parentClassVarIt.isPrivate()) { // Check if the class and its parent have a common variable
|
if (classVarIt.name() == parentClassVarIt.name() && !parentClassVarIt.isPrivate()) { // Check if the class and its parent have a common variable
|
||||||
duplInheritedMembersError(classVarIt.nameToken(), parentClassVarIt.nameToken(),
|
duplInheritedMembersError(classVarIt.nameToken(), parentClassVarIt.nameToken(),
|
||||||
classIt.name(), parentClassIt.type->name(), classVarIt.name(),
|
typeCurrent->name(), parentClassIt.type->name(), classVarIt.name(),
|
||||||
classIt.classScope->type == Scope::eStruct,
|
typeCurrent->classScope->type == Scope::eStruct,
|
||||||
parentClassIt.type->classScope->type == Scope::eStruct);
|
parentClassIt.type->classScope->type == Scope::eStruct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
checkDuplInheritedMembersRecursive(typeCurrent, parentClassIt.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class Scope;
|
||||||
class Settings;
|
class Settings;
|
||||||
class SymbolDatabase;
|
class SymbolDatabase;
|
||||||
class Token;
|
class Token;
|
||||||
|
class Type;
|
||||||
|
|
||||||
/// @addtogroup Checks
|
/// @addtogroup Checks
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -185,6 +186,7 @@ private:
|
||||||
void overrideError(const Function *funcInBase, const Function *funcInDerived);
|
void overrideError(const Function *funcInBase, const Function *funcInDerived);
|
||||||
void thisUseAfterFree(const Token *self, const Token *free, const Token *use);
|
void thisUseAfterFree(const Token *self, const Token *free, const Token *use);
|
||||||
void unsafeClassRefMemberError(const Token *tok, const std::string &varname);
|
void unsafeClassRefMemberError(const Token *tok, const std::string &varname);
|
||||||
|
void checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
|
||||||
CheckClass c(nullptr, settings, errorLogger);
|
CheckClass c(nullptr, settings, errorLogger);
|
||||||
|
|
|
@ -557,6 +557,20 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// #9957
|
||||||
|
checkDuplInheritedMembers("class Base {\n"
|
||||||
|
" public:\n"
|
||||||
|
" int i;\n"
|
||||||
|
"};\n"
|
||||||
|
"class Derived1: public Base {\n"
|
||||||
|
" public:\n"
|
||||||
|
" int j;\n"
|
||||||
|
"};\n"
|
||||||
|
"class Derived2 : public Derived1 {\n"
|
||||||
|
" int i;\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:10]: (warning) The class 'Derived2' defines member variable with name 'i' also defined in its parent class 'Base'.\n", errout.str());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkCopyConstructor(const char code[]) {
|
void checkCopyConstructor(const char code[]) {
|
||||||
|
|
Loading…
Reference in New Issue