Fix #10065 CheckClass::isMemberVar found used member variable with varid 0 (#3843)

This commit is contained in:
chrchr-github 2022-02-20 18:17:47 +01:00 committed by GitHub
parent bfdfe1e607
commit 5574e41b86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 4 deletions

View File

@ -2037,12 +2037,28 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
}
} while (again);
for (const Variable &var : scope->varlist) {
for (const Variable& var : scope->varlist) {
if (var.name() == tok->str()) {
if (tok->varId() == 0)
mSymbolDatabase->debugMessage(tok, "varid0", "CheckClass::isMemberVar found used member variable \'" + tok->str() + "\' with varid 0");
const Token* fqTok = tok;
while (Token::Match(fqTok->tokAt(-2), "%name% ::"))
fqTok = fqTok->tokAt(-2);
if (fqTok->strAt(-1) == "::")
fqTok = fqTok->previous();
bool isMember = tok == fqTok;
std::string scopeStr;
const Scope* curScope = scope;
while (!isMember && curScope && curScope->type != Scope::ScopeType::eGlobal) {
scopeStr.insert(0, curScope->className + " :: ");
isMember = Token::Match(fqTok, scopeStr.c_str());
return !var.isStatic();
curScope = curScope->nestedIn;
}
if (isMember) {
if (tok->varId() == 0)
mSymbolDatabase->debugMessage(tok, "varid0", "CheckClass::isMemberVar found used member variable \'" + tok->str() + "\' with varid 0");
return !var.isStatic();
}
}
}

View File

@ -191,6 +191,7 @@ private:
TEST_CASE(const72); // ticket #10520
TEST_CASE(const73); // ticket #10735
TEST_CASE(const74); // ticket #10671
TEST_CASE(const75); // ticket #10065
TEST_CASE(const_handleDefaultParameters);
TEST_CASE(const_passThisToMemberOfOtherClass);
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
@ -5963,6 +5964,36 @@ private:
ASSERT_EQUALS("", errout.str());
}
void const75() { // #10065
checkConst("namespace N { int i = 0; }\n"
"struct S {\n"
" int i;\n"
" void f() {\n"
" if (N::i) {}\n"
" }\n"
"};\n");
ASSERT_EQUALS("[test.cpp:4]: (performance, inconclusive) Technically the member function 'S::f' can be static (but you may consider moving to unnamed namespace).\n", errout.str());
checkConst("int i = 0;\n"
"struct S {\n"
" int i;\n"
" void f() {\n"
" if (::i) {}\n"
" }\n"
"};\n");
ASSERT_EQUALS("[test.cpp:4]: (performance, inconclusive) Technically the member function 'S::f' can be static (but you may consider moving to unnamed namespace).\n", errout.str());
checkConst("namespace N {\n"
" struct S {\n"
" int i;\n"
" void f() {\n"
" if (N::S::i) {}\n"
" }\n"
" };\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style, inconclusive) Technically the member function 'N::S::f' can be const.\n", errout.str());
}
void const_handleDefaultParameters() {
checkConst("struct Foo {\n"
" void foo1(int i, int j = 0) {\n"