From c8773b891da54c86b61d4222d4054d41b840b985 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sun, 12 Aug 2012 03:13:07 -0700 Subject: [PATCH] Refactorization: Make use of Token::scope() replacing certain indentation counters --- lib/checkbufferoverrun.cpp | 49 +++++------------------------------- lib/checkexceptionsafety.cpp | 16 +++--------- lib/checknullpointer.cpp | 30 ++++++---------------- lib/checkother.cpp | 15 ++--------- lib/checkstl.cpp | 19 ++++++-------- 5 files changed, 26 insertions(+), 103 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 85f8edf3c..139ae0f24 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -829,19 +829,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectornext()) { - if (tok->str() == "{") { - ++indentlevel; - } - - else if (tok->str() == "}") { - --indentlevel; - if (indentlevel < 0) - return; - } - + for (const Token* const end = tok->scope()->classEnd; tok != end; tok = tok->next()) { if (varid != 0 && Token::Match(tok, "%varid% = new|malloc|realloc", varid)) { // Abort break; @@ -1034,22 +1022,9 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo const Token *scope_begin = tok->previous(); assert(scope_begin != 0); - // Count { and } for tok - unsigned int indentlevel = 0; - for (; tok; tok = tok->next()) { - if (tok->str() == "{") { - ++indentlevel; - } - - else if (tok->str() == "}") { - if (indentlevel == 0) - return; - --indentlevel; - } - + for (const Token* const end = tok->scope()->classEnd; tok != end; tok = tok->next()) { // Skip array declarations - else if (Token::Match(tok, "[;{}] %type% *| %var% [") && - tok->strAt(1) != "return") { + if (Token::Match(tok, "[;{}] %type% *| %var% [") && tok->strAt(1) != "return") { tok = tok->tokAt(3); continue; } @@ -1737,21 +1712,9 @@ void CheckBufferOverrun::checkBufferAllocatedWithStrlen() } else continue; - // count { and } for tok - int indentlevel = 0; - for (; tok && tok->next(); tok = tok->next()) { - // To avoid false positives and added complexity, we will only look for - // improper usage of the buffer within the block that it was allocated - if (tok->str() == "{") { - ++indentlevel; - } - - else if (tok->str() == "}") { - --indentlevel; - if (indentlevel < 0) - return; - } - + // To avoid false positives and added complexity, we will only look for + // improper usage of the buffer within the block that it was allocated + for (const Token* const end = tok->scope()->classEnd; tok && tok->next() && tok != end; tok = tok->next()) { // If the buffers are modified, we can't be sure of their sizes if (tok->varId() == srcVarId || tok->varId() == dstVarId) break; diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index c163fbc75..e19b2d01a 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -92,24 +92,14 @@ void CheckExceptionSafety::deallocThrow() if (!var || !(var->isGlobal() || var->isStatic())) continue; - // indentlevel.. - unsigned int indentlevel = 0; - // Token where throw occurs const Token *ThrowToken = 0; // is there a throw after the deallocation? - for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { - if (tok2->str() == "{") - ++indentlevel; - else if (tok2->str() == "}") { - if (indentlevel == 0) - break; - --indentlevel; - } - + const Token* const end2 = tok->scope()->classEnd; + for (const Token *tok2 = tok; tok2 != end2; tok2 = tok2->next()) { // Throw after delete -> Dead pointer - else if (tok2->str() == "throw") { + if (tok2->str() == "throw") { if (_settings->inconclusive) { // For inconclusive checking, throw directly. deallocThrowError(tok2, tok->str()); break; diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 410d92872..72d76c7e3 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -455,17 +455,10 @@ void CheckNullPointer::nullPointerLinkedList() // Make sure there is a "break" or "return" inside the loop. // Without the "break" a null pointer could be dereferenced in the // for statement. - // indentlevel4 is a counter for { and }. When scanning the code with tok4 - unsigned int indentlevel4 = 1; for (const Token *tok4 = scope->classStart; tok4; tok4 = tok4->next()) { - if (tok4->str() == "{") - ++indentlevel4; - else if (tok4->str() == "}") { - if (indentlevel4 <= 1) { - nullPointerError(tok1, var->name(), scope->classDef); - break; - } - --indentlevel4; + if (tok4 == i->classEnd) { + nullPointerError(tok1, var->name(), scope->classDef); + break; } // There is a "break" or "return" inside the loop. @@ -609,19 +602,10 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() } // count { and } using tok2 - unsigned int indentlevel2 = 0; - for (const Token *tok2 = tok1->tokAt(3); tok2; tok2 = tok2->next()) { - if (tok2->str() == "{") - ++indentlevel2; - - else if (tok2->str() == "}") { - if (indentlevel2 == 0) - break; - --indentlevel2; - } - + const Token* const end2 = tok1->scope()->classEnd; + for (const Token *tok2 = tok1->tokAt(3); tok2 != end2; tok2 = tok2->next()) { // label / ?: - else if (tok2->str() == ":") + if (tok2->str() == ":") break; // function call.. @@ -650,7 +634,7 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() break; // return/break at base level => stop checking - else if (indentlevel2 == 0 && (tok2->str() == "return" || tok2->str() == "break")) + else if (tok2->scope()->classEnd == end2 && (tok2->str() == "return" || tok2->str() == "break")) break; // Function call: If the pointer is not a local variable it diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 0fa9d0c18..bcef68ff9 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1435,19 +1435,8 @@ void CheckOther::checkUnreachableCode() if (tok->str() == "break") // If the previous was a break, too: Issue warning duplicateBreakError(secondBreak, inconclusive); else { - unsigned int indent = 0; - for (const Token* tok2 = tok; tok2; tok2 = tok2->previous()) { // Check, if the enclosing scope is a switch (TODO: Can we use SymbolDatabase here?) - if (tok2->str() == "}") - indent++; - else if (indent == 0 && tok2->str() == "{" && tok2->strAt(-1) == ")") { - if (tok2->previous()->link()->strAt(-1) != "switch") { - duplicateBreakError(secondBreak, inconclusive); - break; - } else - break; - } else if (tok2->str() == "{") - indent--; - } + if (tok->scope()->type != Scope::eSwitch) // Check, if the enclosing scope is a switch + duplicateBreakError(secondBreak, inconclusive); } tok = Token::findmatch(secondBreak, "[}:]"); } else if (!Token::Match(secondBreak, "return|}|case|default") && secondBreak->strAt(1) != ":") { // TODO: No bailout for unconditional scopes diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e6b65c8ff..282c95f14 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -680,8 +680,11 @@ void CheckStl::stlBoundries() // Declaring iterator.. if (tok->str() == "<" && Token::Match(tok->previous(), STL_CONTAINER_LIST)) { const std::string& container_name(tok->strAt(-1)); - while (tok && tok->str() != ">") - tok = tok->next(); + if (tok->link()) + tok = tok->link(); + else + while (tok && tok->str() != ">") + tok = tok->next(); if (!tok) break; @@ -691,15 +694,9 @@ void CheckStl::stlBoundries() continue; // Using "iterator < ..." is not allowed - unsigned int indentlevel = 0; - for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { - if (tok2->str() == "{") - ++indentlevel; - else if (tok2->str() == "}") { - if (indentlevel == 0) - break; - --indentlevel; - } else if (Token::Match(tok2, "!!* %varid% <", iteratorid)) { + const Token* const end = tok->scope()->classEnd; + for (const Token *tok2 = tok; tok2 != end; tok2 = tok2->next()) { + if (Token::Match(tok2, "!!* %varid% <", iteratorid)) { stlBoundriesError(tok2, container_name); } else if (Token::Match(tok2, "> %varid% !!.", iteratorid)) { stlBoundriesError(tok2, container_name);