From b2f8161862287f1de900382f5bf9d42aa0734669 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Wed, 28 Dec 2011 16:49:05 +0100 Subject: [PATCH] Rewrite fix of ticket #3415 (Segmentation fault in new check for uninitialized variables): new simplify: 'code ; ({ some_code ; });' to 'code ; some_code ;'; remove the sanity check in checkunusedvar, so when it crashes again it's easy to spot a bigger problem; 'internal' reported 'Token::Match' with simple pattern. 'Tokenizer::tokenize()' refactorings: make one loop with many simple simplifications instead of many loops with one simplification. some style changes. --- lib/checkuninitvar.cpp | 8 +-- lib/tokenize.cpp | 135 ++++++++++++++++++----------------------- 2 files changed, 60 insertions(+), 83 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 4ed08b83a..94075a0f4 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1112,7 +1112,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int } // Inner scope.. - if (Token::Match(tok, "if (")) { + if (Token::simpleMatch(tok, "if (")) { // initialization / usage in condition.. if (checkIfForWhileHead(tok->next(), varid, ispointer, suppressErrors, bool(number_of_if == 0))) return true; @@ -1126,11 +1126,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int // goto the } tok = tok->link(); - // TODO: Make sure "if" blocks are surrounded by {} properly (#3415) - if (!tok) - return true; // bail out - - if (!Token::Match(tok, "} else {")) { + if (!Token::simpleMatch(tok, "} else {")) { if (initif || possibleInitIf) { ++number_of_if; if (number_of_if >= 2) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 25d8f0533..efcc2d3f0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1956,45 +1956,6 @@ bool Tokenizer::tokenize(std::istream &code, createTokens(code); - // replace __LINE__ macro with line number - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (tok->str() == "__LINE__") - tok->str(MathLib::toString(tok->linenr())); - } - - // 'double sharp' token concatenation - { - bool goback = false; - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (goback) { - goback = false; - tok = tok->previous(); - } - // TODO: pattern should be "%var%|%num% ## %var%|%num%" - if (Token::Match(tok, "%any% ## %any%") && - (tok->isName() || tok->isNumber()) && - (tok->tokAt(2)->isName() || tok->tokAt(2)->isNumber())) { - tok->str(tok->str() + tok->strAt(2)); - tok->deleteNext(2); - goback = true; - } - } - } - - // Convert C# code - if (isCSharp()) { - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "%type% [ ] %var% [=;]") && - (!tok->previous() || Token::Match(tok->previous(), "[;{}]"))) { - tok->deleteNext(2); - tok->insertToken("*"); - tok = tok->tokAt(2); - if (tok->next()->str() == "=") - tok = tok->next(); - } - } - } - // if MACRO for (const Token *tok = _tokens; tok; tok = tok->next()) { if (Token::Match(tok, "if|for|while %var% (")) { @@ -2003,35 +1964,6 @@ bool Tokenizer::tokenize(std::istream &code, } } - // Simplify JAVA/C# code - if (isJavaOrCSharp()) { - // better don't call isJava in the loop - bool isJava_ = isJava(); - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (isJava_ && Token::Match(tok, ") throws %var% {")) { - tok->deleteNext(2); - } else if (tok->str() == "private") - tok->str("private:"); - else if (tok->str() == "protected") - tok->str("protected:"); - else if (tok->str() == "public") - tok->str("public:"); - } - } - - // Replace NULL with 0.. - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (tok->str() == "NULL" || tok->str() == "__null" || - tok->str() == "'\\0'" || tok->str() == "'\\x0'") { - tok->str("0"); - } else if (tok->isNumber() && - MathLib::isInt(tok->str()) && - MathLib::toLongNumber(tok->str()) == 0) { - tok->str("0"); - } - } - - // replace inline SQL with "asm()" (Oracle PRO*C). Ticket: #1959 for (Token *tok = _tokens; tok; tok = tok->next()) { if (Token::simpleMatch(tok, "EXEC SQL")) { @@ -2061,6 +1993,63 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + //easy simplifications... + for (Token *tok = _tokens; tok; tok = tok->next()) { + + // replace __LINE__ macro with line number + if (tok->str() == "__LINE__") + tok->str(MathLib::toString(tok->linenr())); + + // 'double sharp' token concatenation + // TODO: pattern should be "%var%|%num% ## %var%|%num%" + while (Token::Match(tok, "%any% ## %any%") && + (tok->isName() || tok->isNumber()) && + (tok->tokAt(2)->isName() || tok->tokAt(2)->isNumber())) { + tok->str(tok->str() + tok->strAt(2)); + tok->deleteNext(2); + } + + //Replace NULL with 0.. + if (tok->str() == "NULL" || tok->str() == "__null" || + tok->str() == "'\\0'" || tok->str() == "'\\x0'") { + tok->str("0"); + } else if (tok->isNumber() && + MathLib::isInt(tok->str()) && + MathLib::toLongNumber(tok->str()) == 0) { + tok->str("0"); + } + + // Combine "- %num%" .. + if (Token::Match(tok, "?|:|,|(|[|=|return|case|sizeof|%op% - %num%")) { + tok->deleteNext(); + tok->next()->str("-" + tok->next()->str()); + } + + // Simplify JAVA/C# code + if (isJava() && Token::Match(tok, ") throws %var% {")) + tok->deleteNext(2); + else if (isJavaOrCSharp() && tok->str() == "private") + tok->str("private:"); + else if (isJavaOrCSharp() && tok->str() == "protected") + tok->str("protected:"); + else if (isJavaOrCSharp() && tok->str() == "public") + tok->str("public:"); + + // Convert exclusive C# code + if (isCSharp() && Token::Match(tok, "%type% [ ] %var% [=;]") && + (!tok->previous() || Token::Match(tok->previous(), "[;{}]"))) { + tok->deleteNext(2); + tok->insertToken("*"); + } + + // simplify round "(" parenthesis between "[;{}] and "{" + if (Token::Match(tok, "[;{}] ( {") && + Token::simpleMatch(tok->linkAt(2), "} ) ;")) { + tok->linkAt(2)->previous()->deleteNext(2); + tok->deleteNext(2); + } + } + // Convert K&R function declarations to modern C simplifyVarDecl(true); simplifyFunctionParameters(); @@ -2083,14 +2072,6 @@ bool Tokenizer::tokenize(std::istream &code, if (!simplifyIfAddBraces()) return false; - // Combine "- %num%" .. - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "?|:|,|(|[|=|return|case|sizeof|%op% - %num%")) { - tok->next()->str("-" + tok->strAt(2)); - tok->next()->deleteNext(); - } - } - // Combine tokens.. for (Token *tok = _tokens; tok && tok->next(); tok = tok->next()) { const char c1 = tok->str()[0]; @@ -2523,7 +2504,7 @@ void Tokenizer::simplifyDefaultAndDeleteInsideClass() for (Token *tok = _tokens; tok; tok = tok->next()) { if (Token::Match(tok, "struct|class %var% :|{")) { unsigned int indentlevel = 0; - for (Token * tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { + for (Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { if (tok2->str() == "{") ++indentlevel; else if (tok2->str() == "}") {