Skip to content

Commit da92ba3

Browse files
authored
Fix #14951: FP unreadVariable with function pointer member (#8768)
1 parent 8745a78 commit da92ba3

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

lib/tokenize.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4549,7 +4549,7 @@ static void setVarIdStructMembers(Token *&tok1,
45494549
return;
45504550
}
45514551

4552-
while (Token::Match(tok->next(), ")| . %name% !!(")) {
4552+
while (Token::Match(tok->next(), ")| . %name%")) {
45534553
// Don't set varid for trailing return type
45544554
if (tok->strAt(1) == ")" && Token::Match(tok->linkAt(1)->tokAt(-1), "%name%|]") && !tok->linkAt(1)->tokAt(-1)->isKeyword() &&
45554555
TokenList::isFunctionHead(tok->linkAt(1), "{;")) {
@@ -4571,6 +4571,8 @@ static void setVarIdStructMembers(Token *&tok1,
45714571
std::map<std::string, nonneg int>& members = structMembers[struct_varid];
45724572
const auto it = utils::as_const(members).find(tok->str());
45734573
if (it == members.cend()) {
4574+
if (Token::Match(tok, "%name% ("))
4575+
break;
45744576
members[tok->str()] = ++varId;
45754577
tok->varId(varId);
45764578
} else {

test/testsymboldatabase.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class TestSymbolDatabase : public TestFixture {
233233
TEST_CASE(rangeBasedFor);
234234

235235
TEST_CASE(memberVar1);
236+
TEST_CASE(memberVar2);
236237
TEST_CASE(arrayMemberVar1);
237238
TEST_CASE(arrayMemberVar2);
238239
TEST_CASE(arrayMemberVar3);
@@ -1864,6 +1865,22 @@ class TestSymbolDatabase : public TestFixture {
18641865
ASSERT(Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;"));
18651866
}
18661867

1868+
void memberVar2() {
1869+
GET_SYMBOL_DB( "struct S { void (*fp)(); };\n"
1870+
"void g();\n"
1871+
"void f() {\n"
1872+
" S s;\n"
1873+
" s.fp = g;\n"
1874+
" s.fp();\n"
1875+
"}\n");
1876+
1877+
ASSERT(db != nullptr);
1878+
const Token *fp1 = Token::findsimplematch(tokenizer.tokens(), "fp =");
1879+
const Token *fp2 = Token::findsimplematch(tokenizer.tokens(), "fp (");
1880+
ASSERT(fp1->varId());
1881+
ASSERT_EQUALS(fp2->varId(), fp1->varId());
1882+
}
1883+
18671884
void arrayMemberVar1() {
18681885
GET_SYMBOL_DB("struct Foo {\n"
18691886
" int x;\n"

test/testunusedvar.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class TestUnusedVar : public TestFixture {
158158
TEST_CASE(localvar71);
159159
TEST_CASE(localvar72);
160160
TEST_CASE(localvar73);
161+
TEST_CASE(localvar74);
161162
TEST_CASE(localvarloops); // loops
162163
TEST_CASE(localvaralias1);
163164
TEST_CASE(localvaralias2); // ticket #1637
@@ -4100,6 +4101,17 @@ class TestUnusedVar : public TestFixture {
41004101
ASSERT_EQUALS("", errout_str());
41014102
}
41024103

4104+
void localvar74() {
4105+
functionVariableUsage("struct S { void (*fp)(); };\n"
4106+
"void g();\n"
4107+
"void f() {\n"
4108+
" S s;\n"
4109+
" s.fp = g;\n"
4110+
" s.fp();\n"
4111+
"}\n");
4112+
ASSERT_EQUALS("", errout_str());
4113+
}
4114+
41034115
void localvarloops() {
41044116
// loops
41054117
functionVariableUsage("void fun(int c) {\n"

0 commit comments

Comments
 (0)