diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1e0f03387..86145bf11 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1979,6 +1979,9 @@ bool Tokenizer::tokenize(std::istream &code, // f(x=g()) => x=g(); f(x) simplifyAssignmentInFunctionCall(); + // x = ({ 123; }); => { x = 123; } + simplifyAssignmentBlock(); + simplifyVariableMultipleAssign(); // Remove redundant parentheses @@ -8560,6 +8563,36 @@ void Tokenizer::simplifyAssignmentInFunctionCall() } } +void Tokenizer::simplifyAssignmentBlock() +{ + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (Token::Match(tok, "[;{}] %var% = ( {")) { + // goto the "} )" + unsigned int indentlevel = 0; + Token *tok2 = tok; + while (NULL != (tok2 = tok2->next())) { + if (tok2->str() == "(" || tok2->str() == "{") + ++indentlevel; + else if (tok2->str() == ")" || tok2->str() == "}") { + if (indentlevel <= 2) + break; + --indentlevel; + } + } + if (indentlevel == 2 && Token::simpleMatch(tok2, "} )")) { + tok2 = tok2->tokAt(-3); + if (Token::Match(tok2, "[;{}] %any% ;") && (tok2->next()->isName() || tok2->next()->isNumber())) { + tok2->insertToken("="); + tok2->insertToken(tok->next()->str()); + tok2->next()->varId(tok->next()->varId()); + tok->deleteNext(3); + tok2->tokAt(5)->deleteNext(); + } + } + } + } +} + // Remove __asm.. void Tokenizer::simplifyAsm() { diff --git a/lib/tokenize.h b/lib/tokenize.h index 6df8a7b7f..daa0fb5d0 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -159,6 +159,9 @@ public: */ void simplifyAssignmentInFunctionCall(); + /** Simplify assignment where rhs is a block : "x=({123;});" => "{x=123;}" */ + void simplifyAssignmentBlock(); + /** * Simplify constant calculations such as "1+2" => "3" * @return true if modifications to token-list are done. diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 3a97f6955..0666c3c9a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -418,6 +418,9 @@ private: // "x += .." => "x = x + .." TEST_CASE(simplifyCompoundAssignment); + // x = ({ 123; }); => { x = 123; } + TEST_CASE(simplifyAssignmentBlock); + // Tokenize C# TEST_CASE(cs); @@ -6708,6 +6711,11 @@ private: ASSERT_EQUALS("; x = g ( ) ; f ( x ) ;", tokenizeAndStringify(";f(x=g());")); } + void simplifyAssignmentBlock() { + ASSERT_EQUALS("; { x = 123 ; } ;", tokenizeAndStringify(";x=({123;});")); + ASSERT_EQUALS("; { x = y ; } ;", tokenizeAndStringify(";x=({y;});")); + } + void cs() { bool simplify = false; bool expand = true;