* Fix #10737 Regression: unusedStructMember * Add test for #9161 * simpleMatch
This commit is contained in:
parent
c3506b5186
commit
190506db40
|
@ -106,16 +106,15 @@ static bool isExecutableScope(const Token* tok)
|
||||||
const Token * tok2 = tok->link()->previous();
|
const Token * tok2 = tok->link()->previous();
|
||||||
if (Token::simpleMatch(tok2, "; }"))
|
if (Token::simpleMatch(tok2, "; }"))
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok2, "{|} }")) {
|
if (tok2 == tok)
|
||||||
const Token* startTok = tok2->str() == "{" ? tok2 : tok2->link();
|
return false;
|
||||||
|
if (Token::simpleMatch(tok2, "} }")) { // inner scope
|
||||||
|
const Token* startTok = tok2->link();
|
||||||
if (Token::Match(startTok->previous(), "do|try|else {"))
|
if (Token::Match(startTok->previous(), "do|try|else {"))
|
||||||
return true;
|
return true;
|
||||||
if (Token::simpleMatch(startTok->previous(), ") {"))
|
if (Token::Match(startTok->previous(), ")|] {"))
|
||||||
return !findLambdaStartToken(tok2);
|
return !findLambdaStartToken(tok2);
|
||||||
if (tok->str() == "{")
|
return isExecutableScope(startTok);
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return isExecutableScope(startTok);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +127,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
// pointer to current scope
|
// pointer to current scope
|
||||||
Scope *scope = &scopeList.back();
|
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;
|
std::stack<std::pair<const Token*, const Scope*>> endInitList;
|
||||||
auto inInitList = [&] {
|
auto inInitList = [&] {
|
||||||
if (endInitList.empty())
|
if (endInitList.empty())
|
||||||
|
|
|
@ -3904,6 +3904,14 @@ private:
|
||||||
" f(p.c_str());\n"
|
" f(p.c_str());\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void uselessCalls() {
|
||||||
|
|
|
@ -67,6 +67,7 @@ private:
|
||||||
TEST_CASE(structmember17); // #10591
|
TEST_CASE(structmember17); // #10591
|
||||||
TEST_CASE(structmember18); // #10684
|
TEST_CASE(structmember18); // #10684
|
||||||
TEST_CASE(structmember19); // #10826, #10848, #10852
|
TEST_CASE(structmember19); // #10826, #10848, #10852
|
||||||
|
TEST_CASE(structmember20); // #10737
|
||||||
|
|
||||||
TEST_CASE(localvar1);
|
TEST_CASE(localvar1);
|
||||||
TEST_CASE(localvar2);
|
TEST_CASE(localvar2);
|
||||||
|
@ -1743,6 +1744,21 @@ private:
|
||||||
settings.enforcedLang = Settings::None;
|
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") {
|
void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
Loading…
Reference in New Issue