Skip to content

Commit 190506d

Browse files
Fix #10737 Regression: unusedStructMember (cppcheck-opensource#3894)
* Fix #10737 Regression: unusedStructMember * Add test for #9161 * simpleMatch
1 parent c3506b5 commit 190506d

3 files changed

Lines changed: 31 additions & 8 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,15 @@ static bool isExecutableScope(const Token* tok)
106106
const Token * tok2 = tok->link()->previous();
107107
if (Token::simpleMatch(tok2, "; }"))
108108
return true;
109-
if (Token::Match(tok2, "{|} }")) {
110-
const Token* startTok = tok2->str() == "{" ? tok2 : tok2->link();
109+
if (tok2 == tok)
110+
return false;
111+
if (Token::simpleMatch(tok2, "} }")) { // inner scope
112+
const Token* startTok = tok2->link();
111113
if (Token::Match(startTok->previous(), "do|try|else {"))
112114
return true;
113-
if (Token::simpleMatch(startTok->previous(), ") {"))
115+
if (Token::Match(startTok->previous(), ")|] {"))
114116
return !findLambdaStartToken(tok2);
115-
if (tok->str() == "{")
116-
return false;
117-
else
118-
return isExecutableScope(startTok);
117+
return isExecutableScope(startTok);
119118
}
120119
return false;
121120
}
@@ -128,7 +127,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
128127
// pointer to current scope
129128
Scope *scope = &scopeList.back();
130129

131-
// Store the edning of init lists
130+
// Store the ending of init lists
132131
std::stack<std::pair<const Token*, const Scope*>> endInitList;
133132
auto inInitList = [&] {
134133
if (endInitList.empty())

test/teststl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3904,6 +3904,14 @@ class TestStl : public TestFixture {
39043904
" f(p.c_str());\n"
39053905
"}\n");
39063906
ASSERT_EQUALS("", errout.str());
3907+
3908+
check("struct S {\n" //#9161
3909+
" const char* f() const noexcept {\n"
3910+
" return (\"\" + m).c_str();\n"
3911+
" }\n"
3912+
" std::string m;\n"
3913+
"};\n", /*inconclusive*/ true);
3914+
ASSERT_EQUALS("[test.cpp:3]: (error) Dangerous usage of c_str(). The value returned by c_str() is invalid after this call.\n", errout.str());
39073915
}
39083916

39093917
void uselessCalls() {

test/testunusedvar.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class TestUnusedVar : public TestFixture {
6767
TEST_CASE(structmember17); // #10591
6868
TEST_CASE(structmember18); // #10684
6969
TEST_CASE(structmember19); // #10826, #10848, #10852
70+
TEST_CASE(structmember20); // #10737
7071

7172
TEST_CASE(localvar1);
7273
TEST_CASE(localvar2);
@@ -1743,6 +1744,21 @@ class TestUnusedVar : public TestFixture {
17431744
settings.enforcedLang = Settings::None;
17441745
}
17451746

1747+
void structmember20() { // #10737
1748+
checkStructMemberUsage("void f() {\n"
1749+
" {\n"
1750+
" }\n"
1751+
" {\n"
1752+
" struct S { int a; };\n"
1753+
" S s{};\n"
1754+
" {\n"
1755+
" if (s.a) {}\n"
1756+
" }\n"
1757+
" }\n"
1758+
"}\n");
1759+
ASSERT_EQUALS("", errout.str());
1760+
}
1761+
17461762
void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
17471763
// Clear the error buffer..
17481764
errout.str("");

0 commit comments

Comments
 (0)