Skip to content

Commit 2a81388

Browse files
committed
Fixed #11102 (False positive: unreadVariable when union in derived struct is used)
1 parent ca9747c commit 2a81388

3 files changed

Lines changed: 45 additions & 24 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,24 +1002,24 @@ void SymbolDatabase::createSymbolDatabaseVariableSymbolTable()
10021002
}
10031003

10041004
// fill in missing variables if possible
1005-
const std::size_t functions = functionScopes.size();
1006-
for (std::size_t i = 0; i < functions; ++i) {
1007-
const Scope *func = functionScopes[i];
1005+
for (const Scope *func: functionScopes) {
10081006
for (const Token *tok = func->bodyStart->next(); tok && tok != func->bodyEnd; tok = tok->next()) {
10091007
// check for member variable
1010-
if (tok->varId() && tok->next() &&
1011-
(tok->next()->str() == "." ||
1012-
(tok->next()->str() == "[" && tok->linkAt(1)->strAt(1) == "."))) {
1013-
const Token *tok1 = tok->next()->str() == "." ? tok->tokAt(2) : tok->linkAt(1)->tokAt(2);
1014-
if (tok1 && tok1->varId() && mVariableList[tok1->varId()] == nullptr) {
1015-
const Variable *var = mVariableList[tok->varId()];
1016-
if (var && var->typeScope()) {
1017-
// find the member variable of this variable
1018-
const Variable *var1 = var->typeScope()->getVariable(tok1->str());
1019-
if (var1) {
1020-
// add this variable to the look up table
1021-
mVariableList[tok1->varId()] = var1;
1022-
}
1008+
if (!Token::Match(tok, "%var% .|["))
1009+
continue;
1010+
const Token* tokDot = tok->next();
1011+
while (Token::simpleMatch(tokDot, "["))
1012+
tokDot = tokDot->link()->next();
1013+
if (!Token::Match(tokDot, ". %var%"))
1014+
continue;
1015+
const Token *member = tokDot->next();
1016+
if (mVariableList[member->varId()] == nullptr) {
1017+
const Variable *var1 = mVariableList[tok->varId()];
1018+
if (var1 && var1->typeScope()) {
1019+
const Variable* memberVar = var1->typeScope()->getVariable(member->str());
1020+
if (memberVar) {
1021+
// add this variable to the look up table
1022+
mVariableList[member->varId()] = memberVar;
10231023
}
10241024
}
10251025
}
@@ -4442,7 +4442,6 @@ void Scope::getVariableList(const Settings* settings, const Token* start, const
44424442

44434443
// Is it a function?
44444444
else if (tok->str() == "{") {
4445-
44464445
tok = tok->link();
44474446
continue;
44484447
}
@@ -4614,13 +4613,18 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
46144613

46154614
const Variable *Scope::getVariable(const std::string &varname) const
46164615
{
4617-
std::list<Variable>::const_iterator iter;
4618-
4619-
for (iter = varlist.begin(); iter != varlist.end(); ++iter) {
4620-
if (iter->name() == varname)
4621-
return &*iter;
4616+
for (const Variable& var: varlist) {
4617+
if (var.name() == varname)
4618+
return &var;
4619+
}
4620+
if (definedType) {
4621+
for (const Type::BaseInfo& baseInfo: definedType->derivedFrom) {
4622+
if (baseInfo.type && baseInfo.type->classScope) {
4623+
if (const Variable* var = baseInfo.type->classScope->getVariable(varname))
4624+
return var;
4625+
}
4626+
}
46224627
}
4623-
46244628
return nullptr;
46254629
}
46264630

test/testimportproject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class TestImportProject : public TestFixture {
352352
ASSERT_EQUALS("lib/", s.includePaths.front());
353353
}
354354

355-
void ignorePaths() {
355+
void ignorePaths() const {
356356
ImportProject::FileSettings fs1, fs2;
357357
fs1.filename = "foo/bar";
358358
fs2.filename = "qwe/rty";

test/testsymboldatabase.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class TestSymbolDatabase : public TestFixture {
184184

185185
TEST_CASE(rangeBasedFor);
186186

187+
TEST_CASE(memberVar1);
187188
TEST_CASE(arrayMemberVar1);
188189
TEST_CASE(arrayMemberVar2);
189190
TEST_CASE(arrayMemberVar3);
@@ -1417,6 +1418,22 @@ class TestSymbolDatabase : public TestFixture {
14171418
ASSERT_EQUALS("signed int *", c->valueType()->str());
14181419
}
14191420

1421+
void memberVar1() {
1422+
GET_SYMBOL_DB("struct Foo {\n"
1423+
" int x;\n"
1424+
"};\n"
1425+
"struct Bar : public Foo {};\n"
1426+
"void f() {\n"
1427+
" struct Bar bar;\n"
1428+
" bar.x = 123;\n" // <- x should get a variable() pointer
1429+
"}");
1430+
1431+
ASSERT(db != nullptr);
1432+
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "x =");
1433+
ASSERT(tok->variable());
1434+
ASSERT(Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;"));
1435+
}
1436+
14201437
void arrayMemberVar1() {
14211438
GET_SYMBOL_DB("struct Foo {\n"
14221439
" int x;\n"

0 commit comments

Comments
 (0)