Fixed #6638: (varid for loop in for statement)

This commit is contained in:
Frank Zingsheim 2015-04-09 19:58:12 +02:00
parent 8a3365c23e
commit d52b031301
2 changed files with 31 additions and 7 deletions

View File

@ -2575,11 +2575,11 @@ void Tokenizer::setVarId()
std::stack<scopeStackEntryType> scopeStack; std::stack<scopeStackEntryType> scopeStack;
scopeStack.push(scopeStackEntryType()); scopeStack.push(scopeStackEntryType());
const Token * functionDeclEnd = nullptr; std::stack<const Token *> functionDeclEndStack;
bool initlist = false; bool initlist = false;
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
if (tok == functionDeclEnd) { if (!functionDeclEndStack.empty() && tok == functionDeclEndStack.top()) {
functionDeclEnd = nullptr; functionDeclEndStack.pop();
if (tok->str() == ":") if (tok->str() == ":")
initlist = true; initlist = true;
else if (tok->str() == ";") { else if (tok->str() == ";") {
@ -2589,16 +2589,20 @@ void Tokenizer::setVarId()
scopeInfo.pop(); scopeInfo.pop();
} else if (tok->str() == "{") } else if (tok->str() == "{")
scopeStack.push(scopeStackEntryType(true, _varId)); scopeStack.push(scopeStackEntryType(true, _varId));
} else if (!functionDeclEnd && !initlist && tok->str()=="(") { } else if (!initlist && tok->str()=="(") {
const Token * newFunctionDeclEnd = nullptr;
if (!scopeStack.top().isExecutable) if (!scopeStack.top().isExecutable)
functionDeclEnd = isFunctionHead(tok, "{:;"); newFunctionDeclEnd = isFunctionHead(tok, "{:;");
else { else {
Token const * tokenLinkNext = tok->link()->next(); Token const * tokenLinkNext = tok->link()->next();
if (tokenLinkNext->str() == "{") // might be for- or while-loop or if-statement if (tokenLinkNext->str() == "{") // might be for- or while-loop or if-statement
functionDeclEnd = tokenLinkNext; newFunctionDeclEnd = tokenLinkNext;
} }
if (functionDeclEnd) if (newFunctionDeclEnd &&
(functionDeclEndStack.empty() || newFunctionDeclEnd != functionDeclEndStack.top())) {
functionDeclEndStack.push(newFunctionDeclEnd);
scopeInfo.push(variableId); scopeInfo.push(variableId);
}
} else if (tok->str() == "{") { } else if (tok->str() == "{") {
// parse anonymous unions as part of the current scope // parse anonymous unions as part of the current scope
if (!(initlist && Token::Match(tok->previous(), "%name%|>|>>") && Token::Match(tok->link(), "} ,|{"))) { if (!(initlist && Token::Match(tok->previous(), "%name%|>|>>") && Token::Match(tok->link(), "} ,|{"))) {

View File

@ -86,6 +86,7 @@ private:
TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef 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(varid56); // function with a throw()
TEST_CASE(varid57); // #6636: new scope by {} TEST_CASE(varid57); // #6636: new scope by {}
TEST_CASE(varid58); // #6638: for loop in for condition
TEST_CASE(varid_cpp_keywords_in_c_code); 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(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
TEST_CASE(varidFunctionCall1); TEST_CASE(varidFunctionCall1);
@ -1023,6 +1024,25 @@ private:
ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp")); ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp"));
} }
void varid58() { // #6638: for loop in for condition
const char code1[] = "void f() {\n"
" for (int i;\n"
" ({for(int i;i;++i){i++;}i++;}),i;\n"
" ({for(int i;i;++i){i++;}i++;}),i++) {\n"
" i++;\n"
" }\n"
"}\n";
const char expected1[] = "\n\n##file 0\n"
"1: void f ( ) {\n"
"2: for ( int i@1 ;\n"
"3: { for ( int i@2 ; i@2 ; ++ i@2 ) { i@2 ++ ; } i@1 ++ ; } , i@1 ;\n"
"4: { for ( int i@3 ; i@3 ; ++ i@3 ) { i@3 ++ ; } i@1 ++ ; } , i@1 ++ ) {\n"
"5: i@1 ++ ;\n"
"6: }\n"
"7: }\n";
ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp"));
}
void varid_cpp_keywords_in_c_code() { void varid_cpp_keywords_in_c_code() {
const char code[] = "void f() {\n" const char code[] = "void f() {\n"
" delete d;\n" " delete d;\n"