Fixed #3188 (Function parser false positive)
This commit is contained in:
parent
085a6285fa
commit
b96ab6ba26
|
@ -1952,6 +1952,10 @@ bool Tokenizer::tokenize(std::istream &code,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert K&R function declarations to modern C
|
||||||
|
simplifyVarDecl(true);
|
||||||
|
simplifyFunctionParameters();
|
||||||
|
|
||||||
// check for simple syntax errors..
|
// check for simple syntax errors..
|
||||||
for (const Token *tok = _tokens; tok; tok = tok->next()) {
|
for (const Token *tok = _tokens; tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "> struct {") &&
|
if (Token::simpleMatch(tok, "> struct {") &&
|
||||||
|
@ -2376,7 +2380,7 @@ bool Tokenizer::tokenize(std::istream &code,
|
||||||
simplifyInitVar();
|
simplifyInitVar();
|
||||||
|
|
||||||
// Split up variable declarations.
|
// Split up variable declarations.
|
||||||
simplifyVarDecl();
|
simplifyVarDecl(false);
|
||||||
|
|
||||||
// f(x=g()) => x=g(); f(x)
|
// f(x=g()) => x=g(); f(x)
|
||||||
simplifyAssignmentInFunctionCall();
|
simplifyAssignmentInFunctionCall();
|
||||||
|
@ -2420,7 +2424,7 @@ bool Tokenizer::tokenize(std::istream &code,
|
||||||
simplifyInitVar();
|
simplifyInitVar();
|
||||||
|
|
||||||
// Split up variable declarations.
|
// Split up variable declarations.
|
||||||
simplifyVarDecl();
|
simplifyVarDecl(false);
|
||||||
|
|
||||||
if (!preprocessorCondition) {
|
if (!preprocessorCondition) {
|
||||||
setVarId();
|
setVarId();
|
||||||
|
@ -4222,9 +4226,8 @@ bool Tokenizer::simplifyTokenList()
|
||||||
simplifyInitVar();
|
simplifyInitVar();
|
||||||
|
|
||||||
// Simplify variable declarations
|
// Simplify variable declarations
|
||||||
simplifyVarDecl();
|
simplifyVarDecl(false);
|
||||||
|
|
||||||
simplifyFunctionParameters();
|
|
||||||
elseif();
|
elseif();
|
||||||
simplifyErrNoInWhile();
|
simplifyErrNoInWhile();
|
||||||
simplifyIfAssign();
|
simplifyIfAssign();
|
||||||
|
@ -5629,7 +5632,7 @@ static void incdec(std::string &value, const std::string &op)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Tokenizer::simplifyVarDecl()
|
void Tokenizer::simplifyVarDecl(bool only_k_r_fpar)
|
||||||
{
|
{
|
||||||
// Split up variable declarations..
|
// Split up variable declarations..
|
||||||
// "int a=4;" => "int a; a=4;"
|
// "int a=4;" => "int a; a=4;"
|
||||||
|
@ -5640,6 +5643,18 @@ void Tokenizer::simplifyVarDecl()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (only_k_r_fpar) {
|
||||||
|
if (tok->str() == "(" || tok->str() == "{") {
|
||||||
|
tok = tok->link();
|
||||||
|
if (!tok)
|
||||||
|
break;
|
||||||
|
if (tok->next() && Token::Match(tok, ") !!{"))
|
||||||
|
tok = tok->next();
|
||||||
|
else continue;
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|)|public:|protected:|private:"))
|
if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|)|public:|protected:|private:"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -220,8 +220,9 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify variable declarations (split up)
|
* Simplify variable declarations (split up)
|
||||||
|
* \param only_k_r_fpar Only simplify K&R function parameters
|
||||||
*/
|
*/
|
||||||
void simplifyVarDecl();
|
void simplifyVarDecl(bool only_k_r_fpar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify variable initialization
|
* Simplify variable initialization
|
||||||
|
|
|
@ -98,6 +98,8 @@ private:
|
||||||
TEST_CASE(hasMissingInlineClassFunctionReturningFunctionPointer);
|
TEST_CASE(hasMissingInlineClassFunctionReturningFunctionPointer);
|
||||||
TEST_CASE(hasClassFunctionReturningFunctionPointer);
|
TEST_CASE(hasClassFunctionReturningFunctionPointer);
|
||||||
|
|
||||||
|
TEST_CASE(parseFunctionCorrect);
|
||||||
|
|
||||||
TEST_CASE(hasGlobalVariables1);
|
TEST_CASE(hasGlobalVariables1);
|
||||||
TEST_CASE(hasGlobalVariables2);
|
TEST_CASE(hasGlobalVariables2);
|
||||||
TEST_CASE(hasGlobalVariables3);
|
TEST_CASE(hasGlobalVariables3);
|
||||||
|
@ -535,6 +537,18 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parseFunctionCorrect() {
|
||||||
|
// ticket 3188 - "if" statement parsed as function
|
||||||
|
GET_SYMBOL_DB("void func(i) int i; { if (i == 1) return; }\n")
|
||||||
|
ASSERT(db != NULL);
|
||||||
|
|
||||||
|
// 3 scopes: Global, function, if
|
||||||
|
ASSERT_EQUALS(3, db->scopeList.size());
|
||||||
|
|
||||||
|
ASSERT(tokenizer.getFunctionTokenByName("func") != NULL);
|
||||||
|
ASSERT(tokenizer.getFunctionTokenByName("if") == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void hasGlobalVariables1() {
|
void hasGlobalVariables1() {
|
||||||
GET_SYMBOL_DB("int i;\n")
|
GET_SYMBOL_DB("int i;\n")
|
||||||
|
|
||||||
|
|
|
@ -4114,7 +4114,7 @@ private:
|
||||||
|
|
||||||
const std::string actual(tokenizeAndStringify(code));
|
const std::string actual(tokenizeAndStringify(code));
|
||||||
|
|
||||||
ASSERT_EQUALS("void foo ( a , b ) unsigned int a ; unsigned int b ; { }", actual);
|
ASSERT_EQUALS("void foo ( unsigned int a , unsigned int b ) { }", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vardecl3() {
|
void vardecl3() {
|
||||||
|
|
Loading…
Reference in New Issue