Checking in fix for issue 9957 - - False negative: duplInheritedMember (#2964)

This commit is contained in:
abhijit-sawant 2020-12-21 01:14:52 -05:00 committed by GitHub
parent 69f5a0df72
commit 7d6fc23022
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 13 deletions

View File

@ -2439,22 +2439,28 @@ void CheckClass::checkDuplInheritedMembers()
// Iterate over all classes
for (const Type &classIt : mSymbolDatabase->typeList) {
// Iterate over the parent classes
for (const Type::BaseInfo &parentClassIt : classIt.derivedFrom) {
// Check if there is info about the 'Base' class
if (!parentClassIt.type || !parentClassIt.type->classScope)
continue;
// Check if they have a member variable in common
for (const Variable &classVarIt : classIt.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
duplInheritedMembersError(classVarIt.nameToken(), parentClassVarIt.nameToken(),
classIt.name(), parentClassIt.type->name(), classVarIt.name(),
classIt.classScope->type == Scope::eStruct,
parentClassIt.type->classScope->type == Scope::eStruct);
}
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
if (!parentClassIt.type || !parentClassIt.type->classScope)
continue;
// Check if they have a member variable in common
for (const Variable &classVarIt : typeCurrent->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
duplInheritedMembersError(classVarIt.nameToken(), parentClassVarIt.nameToken(),
typeCurrent->name(), parentClassIt.type->name(), classVarIt.name(),
typeCurrent->classScope->type == Scope::eStruct,
parentClassIt.type->classScope->type == Scope::eStruct);
}
}
}
checkDuplInheritedMembersRecursive(typeCurrent, parentClassIt.type);
}
}

View File

@ -38,6 +38,7 @@ class Scope;
class Settings;
class SymbolDatabase;
class Token;
class Type;
/// @addtogroup Checks
/// @{
@ -185,6 +186,7 @@ private:
void overrideError(const Function *funcInBase, const Function *funcInDerived);
void thisUseAfterFree(const Token *self, const Token *free, const Token *use);
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 {
CheckClass c(nullptr, settings, errorLogger);

View File

@ -557,6 +557,20 @@ private:
"}");
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[]) {