Fixed #6636: (False positive unreadVariable - scope analysis seems to fail to False positive unreadVariable)
Bug was introduced by 1f5265c1bd
This commit is contained in:
parent
d563bd73f4
commit
648ee95f31
|
@ -79,6 +79,17 @@ static const Token * isFunctionHead(const Token *tok, const std::string &endsWit
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool isClassStructUnionStart(const Token * tok)
|
||||
{
|
||||
if (tok->str() != "{")
|
||||
return false;
|
||||
const Token * tok2 = tok->previous();
|
||||
while (tok2 && !Token::Match(tok2, "class|struct|union|{|;"))
|
||||
tok2 = tok2->previous();
|
||||
return Token::Match(tok2, "class|struct|union");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Tokenizer::Tokenizer() :
|
||||
|
@ -2590,14 +2601,14 @@ void Tokenizer::setVarId()
|
|||
scopeInfo.push(variableId);
|
||||
} else if (tok->str() == "{") {
|
||||
// parse anonymous unions as part of the current scope
|
||||
if (!(tok->strAt(-1) == "union" && Token::simpleMatch(tok->link(), "} ;")) &&
|
||||
!(initlist && Token::Match(tok->previous(), "%name%|>|>>") && Token::Match(tok->link(), "} ,|{"))) {
|
||||
if (!(initlist && Token::Match(tok->previous(), "%name%|>|>>") && Token::Match(tok->link(), "} ,|{"))) {
|
||||
bool isExecutable;
|
||||
if (tok->strAt(-1) == ")" || Token::Match(tok->tokAt(-2), ") %type%") ||
|
||||
(initlist && tok->strAt(-1) == "}")) {
|
||||
isExecutable = true;
|
||||
} else {
|
||||
isExecutable = (initlist || tok->strAt(-1) == "else");
|
||||
isExecutable = ((scopeStack.top().isExecutable || initlist || tok->strAt(-1) == "else") &&
|
||||
!isClassStructUnionStart(tok));
|
||||
scopeInfo.push(variableId);
|
||||
}
|
||||
initlist = false;
|
||||
|
|
|
@ -85,6 +85,7 @@ private:
|
|||
TEST_CASE(varid54); // hang
|
||||
TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef
|
||||
TEST_CASE(varid56); // function with a throw()
|
||||
TEST_CASE(varid57); // #6636: new scope by {}
|
||||
TEST_CASE(varid_cpp_keywords_in_c_code);
|
||||
TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
|
||||
TEST_CASE(varidFunctionCall1);
|
||||
|
@ -991,6 +992,37 @@ private:
|
|||
ASSERT_EQUALS(expected3, tokenize(code3, false, "test.cpp"));
|
||||
}
|
||||
|
||||
void varid57() { // #6636: new scope by {}
|
||||
const char code1[] = "void SmoothPath() {\n"
|
||||
" {\n" // new scope
|
||||
" float dfx = (p2p0.x > 0.0f)?\n"
|
||||
" ((n0->xmax() * SQUARE_SIZE) - p0.x):\n"
|
||||
" ((n0->xmin() * SQUARE_SIZE) - p0.x);\n"
|
||||
" float tx = dfx / dx;\n"
|
||||
" if (hEdge) {\n"
|
||||
" }\n"
|
||||
" if (vEdge) {\n"
|
||||
" pi.z = tx;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
const char expected1[] = "\n\n##file 0\n"
|
||||
"1: void SmoothPath ( ) {\n"
|
||||
"2:\n"
|
||||
"3: float dfx@1 ; dfx@1 = ( p2p0 . x > 0.0f ) ?\n"
|
||||
"4: ( ( n0 . xmax ( ) * SQUARE_SIZE ) - p0 . x ) :\n"
|
||||
"5: ( ( n0 . xmin ( ) * SQUARE_SIZE ) - p0 . x ) ;\n"
|
||||
"6: float tx@2 ; tx@2 = dfx@1 / dx ;\n"
|
||||
"7: if ( hEdge ) {\n"
|
||||
"8: }\n"
|
||||
"9: if ( vEdge ) {\n"
|
||||
"10: pi . z = tx@2 ;\n"
|
||||
"11: }\n"
|
||||
"12:\n"
|
||||
"13: }\n";
|
||||
ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp"));
|
||||
}
|
||||
|
||||
void varid_cpp_keywords_in_c_code() {
|
||||
const char code[] = "void f() {\n"
|
||||
" delete d;\n"
|
||||
|
|
Loading…
Reference in New Issue