1)Fixed ticket #3184 (Improve Tokenizer: improve simplifyMulAnd to simplify weirder code);

2)Fix a test case inside TestSimplifyTokens::flowControl.
This commit is contained in:
Edoardo Prezioso 2011-12-09 20:47:51 +01:00
parent f46cf5fd65
commit 7d12951da0
4 changed files with 97 additions and 33 deletions

View File

@ -1841,22 +1841,62 @@ void Tokenizer::simplifyTypedef()
}
}
void Tokenizer::simplifyMulAnd()
void Tokenizer::simplifyMulAndParens()
{
for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "[;{}] *")) {
//fix Ticket #2784
if (Token::Match(tok->next(), "* & %any% =")) {
tok->deleteNext(); //del *
tok->deleteNext(); //del &
continue;
for (Token *tok = _tokens->tokAt(3); tok; tok = tok->next()) {
if (tok->isName()) {
//fix ticket #2784 - improved by ticket #3184
unsigned int closedpars = 0;
Token *tokend = tok->next();
Token *tokbegin = tok->previous();
while (tokend && tokend->str() == ")") {
++closedpars;
tokend = tokend->next();
}
if (Token::Match(tok->next(), "* ( & %any% ) =")) {
tok->deleteNext(); //del *
tok->deleteNext(); //del (
tok->deleteNext(); //del &
tok->next()->deleteNext(); //del )
if (!tokend || !(tokend->isAssignmentOp()))
continue;
while (tokbegin && (tokbegin->str() == "&" || tokbegin->str() == "(")) {
if (tokbegin->str() == "&") {
if (Token::Match(tokbegin->tokAt(-2), "[;{}&(] *")) {
//remove '* &'
tokbegin = tokbegin->tokAt(-2);
tokbegin->deleteNext(2);
} else if (Token::Match(tokbegin->tokAt(-3), "[;{}&(] * (")) {
if (!closedpars)
break;
--closedpars;
//remove ')'
tok->deleteNext();
//remove '* ( &'
tokbegin = tokbegin->tokAt(-3);
tokbegin->deleteNext(3);
} else
break;
} else if (tokbegin->str() == "(") {
if (!closedpars)
break;
//find consecutive opening parentheses
unsigned int openpars = 0;
while (tokbegin && tokbegin->str() == "(" && openpars <= closedpars) {
++openpars;
tokbegin = tokbegin->previous();
}
if (!tokbegin || openpars > closedpars)
break;
if ((openpars == closedpars && Token::Match(tokbegin, "[;{}]")) ||
Token::Match(tokbegin->tokAt(-2), "[;{}&(] * &") ||
Token::Match(tokbegin->tokAt(-3), "[;{}&(] * ( &")) {
//remove the excessive parentheses around the variable
while (openpars--) {
tok->deleteNext();
tokbegin->deleteNext();
--closedpars;
}
} else
break;
}
}
}
}
@ -1908,9 +1948,6 @@ bool Tokenizer::tokenize(std::istream &code,
}
}
// simplify '[;{}] * & %any% =' to '%any% ='
simplifyMulAnd();
// Convert C# code
if (_files[0].find(".cs")) {
for (Token *tok = _tokens; tok; tok = tok->next()) {
@ -2062,6 +2099,9 @@ bool Tokenizer::tokenize(std::istream &code,
// simplify labels..
labels();
// simplify '[;{}] * & ( %any% ) =' to '%any% ='
simplifyMulAndParens();
// ";a+=b;" => ";a=a+b;"
simplifyCompoundAssignment();

View File

@ -145,9 +145,10 @@ public:
static void eraseDeadCode(Token *begin, const Token *end);
/**
* Simplify '* & %any% =' to '%any% ='
* Simplify '* & ( %var% ) =' or any combination of '* &' and '()'
* parentheses around '%var%' to '%var% ='
*/
void simplifyMulAnd(void);
void simplifyMulAndParens(void);
/**
* Get parameter name of function

View File

@ -3193,7 +3193,7 @@ private:
{
std::string code = "int f() { "
"switch (x) { case 1: " + *it + "; bar(); tack; { ticak(); " + *it + " } " + *it + " "
"switch (x) { case 1: " + *it + "; bar(); tack; { ticak(); " + *it + " } " + *it + ";"
"case 2: " + *it + "; { random(); } tack(); "
"switch(y) { case 1: " + *it + "; case 2: " + *it + "; } "
"" + *it + "; } " + *it + "; }";

View File

@ -258,7 +258,7 @@ private:
TEST_CASE(simplify_constants2);
TEST_CASE(simplify_constants3);
TEST_CASE(simplify_null);
TEST_CASE(simplifyMulAnd); // #2784
TEST_CASE(simplifyMulAndParens); // Ticket #2784 + #3184
TEST_CASE(vardecl1);
TEST_CASE(vardecl2);
@ -4211,20 +4211,43 @@ private:
ASSERT_EQUALS(expected, tokenizeAndStringify(code,true));
}
void simplifyMulAnd() {
void simplifyMulAndParens() {
// (error) Resource leak
ASSERT_EQUALS(
"void f ( ) { int f ; f = open ( ) ; }",
tokenizeAndStringify(
"void f() {int f; *&f=open(); }"
)
);
ASSERT_EQUALS(
"void f ( ) { int f ; f = open ( ) ; }",
tokenizeAndStringify(
"void f() {int f; *(&f)=open(); }"
)
);
const char code[] = "void f() {"
" *&n1=open();"
" *&(n2)=open();"
" *(&n3)=open();"
" *&*&n4=open();"
" *&*&*&(n5)=open();"
" *&*&(*&n6)=open();"
" *&*(&*&n7)=open();"
" *(&*&n8)=open();"
" *&(*&*&(*&n9))=open();"
" (n10) = open();"
" ((n11)) = open();"
" ((*&n12))=open();"
" *(&(*&n13))=open();"
" ((*&(*&n14)))=open();"
" ((*&(*&n15)))+=10;"
"}";
const char expected[] = "void f ( ) {"
" n1 = open ( ) ;"
" n2 = open ( ) ;"
" n3 = open ( ) ;"
" n4 = open ( ) ;"
" n5 = open ( ) ;"
" n6 = open ( ) ;"
" n7 = open ( ) ;"
" n8 = open ( ) ;"
" n9 = open ( ) ;"
" n10 = open ( ) ;"
" n11 = open ( ) ;"
" n12 = open ( ) ;"
" n13 = open ( ) ;"
" n14 = open ( ) ;"
" n15 = n15 + 10 ; "
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
}
void vardecl1() {