Fix #10737 Regression: unusedStructMember (#3894)

* Fix #10737 Regression: unusedStructMember

* Add test for #9161

* simpleMatch
This commit is contained in:
chrchr-github 2022-03-13 06:27:17 +01:00 committed by GitHub
parent c3506b5186
commit 190506db40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 8 deletions

View File

@ -106,16 +106,15 @@ static bool isExecutableScope(const Token* tok)
const Token * tok2 = tok->link()->previous();
if (Token::simpleMatch(tok2, "; }"))
return true;
if (Token::Match(tok2, "{|} }")) {
const Token* startTok = tok2->str() == "{" ? tok2 : tok2->link();
if (tok2 == tok)
return false;
if (Token::simpleMatch(tok2, "} }")) { // inner scope
const Token* startTok = tok2->link();
if (Token::Match(startTok->previous(), "do|try|else {"))
return true;
if (Token::simpleMatch(startTok->previous(), ") {"))
if (Token::Match(startTok->previous(), ")|] {"))
return !findLambdaStartToken(tok2);
if (tok->str() == "{")
return false;
else
return isExecutableScope(startTok);
return isExecutableScope(startTok);
}
return false;
}
@ -128,7 +127,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
// pointer to current scope
Scope *scope = &scopeList.back();
// Store the edning of init lists
// Store the ending of init lists
std::stack<std::pair<const Token*, const Scope*>> endInitList;
auto inInitList = [&] {
if (endInitList.empty())

View File

@ -3904,6 +3904,14 @@ private:
" f(p.c_str());\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct S {\n" //#9161
" const char* f() const noexcept {\n"
" return (\"\" + m).c_str();\n"
" }\n"
" std::string m;\n"
"};\n", /*inconclusive*/ true);
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());
}
void uselessCalls() {

View File

@ -67,6 +67,7 @@ private:
TEST_CASE(structmember17); // #10591
TEST_CASE(structmember18); // #10684
TEST_CASE(structmember19); // #10826, #10848, #10852
TEST_CASE(structmember20); // #10737
TEST_CASE(localvar1);
TEST_CASE(localvar2);
@ -1743,6 +1744,21 @@ private:
settings.enforcedLang = Settings::None;
}
void structmember20() { // #10737
checkStructMemberUsage("void f() {\n"
" {\n"
" }\n"
" {\n"
" struct S { int a; };\n"
" S s{};\n"
" {\n"
" if (s.a) {}\n"
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
// Clear the error buffer..
errout.str("");