diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 551c3a47543..9b9d40a777e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1289,7 +1289,7 @@ void CheckOtherImpl::checkVariableScope() tok = tok->link(); // parse else if blocks.. - } else if (Token::simpleMatch(tok, "else { if (") && tok->next()->isSimplifiedScope() && Token::simpleMatch(tok->linkAt(3), ") {")) { + } else if (Token::simpleMatch(tok, "else { if (") && tok->next()->isInsertedBrace() && Token::simpleMatch(tok->linkAt(3), ") {")) { tok = tok->next(); } else if (tok->varId() == var->declarationId() || tok->str() == "goto") { reduce = false; @@ -1415,7 +1415,7 @@ bool CheckOtherImpl::checkInnerScope(const Token *tok, const Variable* var, bool if (scope->type == ScopeType::eSwitch) return false; // Used in outer switch scope - unsafe or impossible to reduce scope - if (scope->bodyStart && scope->bodyStart->isSimplifiedScope()) + if (scope->bodyStart && scope->bodyStart->isSimplifiedIfInitStmt()) return false; // simplified if/for/switch init statement } if (var->isArrayOrPointer()) { diff --git a/lib/token.h b/lib/token.h index ca945fcab22..3328af31fa0 100644 --- a/lib/token.h +++ b/lib/token.h @@ -732,11 +732,11 @@ class CPPCHECKLIB Token { setFlag(fIsTemplate, b); } - bool isSimplifiedScope() const { - return getFlag(fIsSimplifedScope); + bool isSimplifiedIfInitStmt() const { + return getFlag(fIsSimplifiedIfInitStmt); } - void isSimplifiedScope(bool b) { - setFlag(fIsSimplifedScope, b); + void isSimplifiedIfInitStmt(bool b) { + setFlag(fIsSimplifiedIfInitStmt, b); } bool isFinalType() const { @@ -767,6 +767,14 @@ class CPPCHECKLIB Token { setFlag(fIsAnonymous, b); } + bool isInsertedBrace() const { + return getFlag(fIsInsertedBrace); + } + Token* isInsertedBrace(bool b) { + setFlag(fIsInsertedBrace, b); + return this; + } + // cppcheck-suppress unusedFunction bool isBitfield() const { return mImpl->mBits >= 0; @@ -1498,7 +1506,7 @@ class CPPCHECKLIB Token { fIsImplicitInt = (1ULL << 33), // Is "int" token implicitly added? fIsInline = (1ULL << 34), // Is this a inline type fIsTemplate = (1ULL << 35), - fIsSimplifedScope = (1ULL << 36), // scope added when simplifying e.g. if (int i = ...; ...) + fIsSimplifiedIfInitStmt = (1ULL << 36), // simplified if/switch/while init statement e.g. if (int i = ...; ...) => { int i = ...; if (..) .. } fIsRemovedVoidParameter = (1ULL << 37), // A void function parameter has been removed fIsIncompleteConstant = (1ULL << 38), fIsRestrict = (1ULL << 39), // Is this a restrict pointer type @@ -1508,6 +1516,7 @@ class CPPCHECKLIB Token { fIsInitComma = (1ULL << 43), // Is this comma located inside some {..}. i.e: {1,2,3,4} fIsInitBracket = (1ULL << 44), // Is this bracket used as a part of variable initialization i.e: int a{5}, b(2); fIsAnonymous = (1ULL << 45), // Is this a token added for an unnamed member + fIsInsertedBrace = (1ULL << 46), // brace added when simplifying e.g. if (x) f(); => if (x) { f(); } }; enum : std::uint8_t { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f97057ddb0f..a8f675bbc97 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6218,6 +6218,8 @@ void Tokenizer::dump(std::ostream &out) const } if (tok->isRemovedVoidParameter()) outs += " isRemovedVoidParameter=\"true\""; + if (tok->isInsertedBrace()) + outs += " isInsertedBrace=\"true\""; if (tok->isSplittedVarDeclComma()) outs += " isSplittedVarDeclComma=\"true\""; if (tok->isSplittedVarDeclEq()) @@ -7004,10 +7006,12 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition) tokAfterCondition->previous()->insertToken("{"); Token * tokOpenBrace=tokAfterCondition->previous(); tokOpenBrace->column(tokAfterCondition->column()); + tokOpenBrace->isInsertedBrace(true); tokEnd->insertToken("}"); Token * tokCloseBrace=tokEnd->next(); tokCloseBrace->column(tokEnd->column()); + tokCloseBrace->isInsertedBrace(true); Token::createMutualLinks(tokOpenBrace,tokCloseBrace); tokBracesEnd=tokCloseBrace; @@ -8038,8 +8042,8 @@ void Tokenizer::elseif() if (Token::Match(tok2, "}|;")) { if (tok2->next() && tok2->strAt(1) != "else") { - tok->insertToken("{")->isSimplifiedScope(true); - tok2->insertToken("}")->isSimplifiedScope(true); + tok->insertToken("{")->isInsertedBrace(true); + tok2->insertToken("}")->isInsertedBrace(true); Token::createMutualLinks(tok->next(), tok2->next()); break; } @@ -8105,7 +8109,8 @@ void Tokenizer::simplifyIfSwitchForInit() tok->str("{"); endscope->insertToken("}"); Token::createMutualLinks(tok, endscope->next()); - tok->isSimplifiedScope(true); + tok->isInsertedBrace(true); + tok->isSimplifiedIfInitStmt(true); } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 6e5ea0f785f..e56ffa3d8bb 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -140,6 +140,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(whileAddBraces); TEST_CASE(whileAddBracesLabels); + TEST_CASE(whileAddBracesDump); TEST_CASE(doWhileAddBraces); TEST_CASE(doWhileAddBracesLabels); @@ -1532,6 +1533,17 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("", filter_valueflow(errout_str())); } + void whileAddBracesDump() { + const char code[] = "void f(){while(a);}"; + SimpleTokenizer tokenizer(settingsDefault, *this, false); + ASSERT(tokenizer.tokenize(code)); + ASSERT(Token::simpleMatch(tokenizer.tokens(), "void f ( ) { while ( a ) { ; } }")); + std::ostringstream ostr; + tokenizer.dump(ostr); + const std::string dump = ostr.str(); + ASSERT(dump.find("isInsertedBrace=\"true\"") != std::string::npos); + } + void doWhileAddBraces() { { const char code[] = "{do ; while (0);}";