Fixed #6636: (False positive unreadVariable - scope analysis seems to fail to False positive unreadVariable)

Bug was introduced by 1f5265c1bd
This commit is contained in:
Frank Zingsheim 2015-04-08 20:30:41 +02:00 committed by Alexander Mai
parent d563bd73f4
commit 648ee95f31
2 changed files with 46 additions and 3 deletions

View File

@ -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;

View File

@ -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"