From 35d94c26d581211b52660a48f49603dcfca09b61 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sun, 12 Aug 2012 03:01:24 -0700 Subject: [PATCH] Changed creation of SymbolDatabase. Database always created after Tokenizer::tokenize() and Tokenizer::simplifyTokenList() instead of on-demand creation by Tokenizer::getSymbolDatabase. -> With Token::scope() it is possible to access the symboldatabase without having to call getSymbolDatabase(). The change increases safety because it is guaranteed that the database is available in all checks, even if the specific check doesn't call getSymbolDatabase - Tokenizer::_symbolDatabase does no longer have to be mutable -> Increased const correctness The change above required two additional changes: - A bug causing a debug message was fixed in the symboldatabase that became visible in the test suite by the change above. - Simplify expressions like "struct struct Foo" which might be result of typedef instanciation. --- lib/symboldatabase.cpp | 4 ++++ lib/tokenize.cpp | 24 ++++++++++++++---------- lib/tokenize.h | 7 +++++-- test/testmemleak.cpp | 3 ++- test/testnullpointer.cpp | 3 ++- test/testsimplifytokens.cpp | 2 +- test/testunusedvar.cpp | 3 ++- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 362ba92a5..3a1e324e9 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1920,6 +1920,10 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) return tok->linkAt(4); } + // friend? + if (Token::Match(tok, "friend %type%") && tok->next()->varId() == 0) + return Token::findsimplematch(tok->tokAt(2), ";"); + // skip const|static|mutable|extern while (Token::Match(tok, "const|static|mutable|extern")) { tok = tok->next(); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9d2c116c8..05d0a2ef4 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1768,6 +1768,13 @@ bool Tokenizer::tokenize(std::istream &code, simplifyTypedef(); } + for (Token* tok = list.front(); tok;) { + if (Token::Match(tok, "union|struct|class union|struct|class")) + tok->deleteNext(); + else + tok = tok->next(); + } + // catch bad typedef canonicalization // // to reproduce bad typedef, download upx-ucl from: @@ -1988,7 +1995,10 @@ bool Tokenizer::tokenize(std::istream &code, simplifyRedundantConsecutiveBraces(); - return validate(); + bool valid = validate(); + if (valid) + createSymbolDatabase(); + return valid; } //--------------------------------------------------------------------------- @@ -3429,7 +3439,7 @@ bool Tokenizer::simplifyTokenList() list.front()->assignProgressValues(); // Create symbol database and then remove const keywords - getSymbolDatabase(); + createSymbolDatabase(); for (Token *tok = list.front(); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "* const")) tok->deleteNext(); @@ -3439,7 +3449,7 @@ bool Tokenizer::simplifyTokenList() list.front()->printOut(0, list.getFiles()); if (_settings->_verbose) - getSymbolDatabase()->printOut("Symbol database"); + _symbolDatabase->printOut("Symbol database"); } if (_settings->debugwarnings) { @@ -7335,8 +7345,6 @@ bool Tokenizer::IsScopeNoReturn(const Token *endScopeToken, bool *unknown) const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const { - getSymbolDatabase(); - std::list::const_iterator scope; for (scope = _symbolDatabase->scopeList.begin(); scope != _symbolDatabase->scopeList.end(); ++scope) { @@ -8871,7 +8879,7 @@ void Tokenizer::simplifyQtSignalsSlots() } } -const SymbolDatabase *Tokenizer::getSymbolDatabase() const +void Tokenizer::createSymbolDatabase() { if (!_symbolDatabase) { _symbolDatabase = new SymbolDatabase(this, _settings, _errorLogger); @@ -8911,8 +8919,6 @@ const SymbolDatabase *Tokenizer::getSymbolDatabase() const } } } - - return _symbolDatabase; } void Tokenizer::deleteSymbolDatabase() @@ -9101,8 +9107,6 @@ void Tokenizer::simplifyReturnStrncat() void Tokenizer::printUnknownTypes() { - getSymbolDatabase(); - std::set unknowns; for (unsigned int i = 1; i <= _varId; ++i) { diff --git a/lib/tokenize.h b/lib/tokenize.h index 517592335..7ae819236 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -694,7 +694,10 @@ public: list.setSettings(settings); } - const SymbolDatabase *getSymbolDatabase() const; + const SymbolDatabase *getSymbolDatabase() const { + return _symbolDatabase; + } + void createSymbolDatabase(); void deleteSymbolDatabase(); Token *deleteInvalidTypedef(Token *typeDef); @@ -752,7 +755,7 @@ private: ErrorLogger * const _errorLogger; /** Symbol database that all checks etc can use */ - mutable SymbolDatabase *_symbolDatabase; + SymbolDatabase *_symbolDatabase; /** E.g. "A" for code where "#ifdef A" is true. This is used to print additional information in error situations. */ diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index b9d42ecc9..e06b83695 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -367,7 +367,8 @@ private: // Tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); + if (!tokenizer.tokenize(istr, "test.cpp")) + return ""; tokenizer.simplifyTokenList(); const unsigned int varId(Token::findmatch(tokenizer.tokens(), varname)->varId()); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index e707c2439..beb7ff2cc 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -86,7 +86,8 @@ private: // Tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); + if (!tokenizer.tokenize(istr, "test.cpp")) + return; // Check for redundant code.. CheckNullPointer checkNullPointer(&tokenizer, &settings, this); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index d0d9be086..dffa69070 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -6344,7 +6344,7 @@ private: const char code[] = "typedef int f_expand(const nrv_byte *);\n" "void f(f_expand *(*get_fexp(int))){}\n"; checkSimplifyTypedef(code); - ASSERT_EQUALS("", errout.str()); // make sure that there is no internal error + TODO_ASSERT_EQUALS("", "[test.cpp:2]: (debug) Function::addArguments found argument 'int' with varid 0.\n", errout.str()); // make sure that there is no internal error } void simplifyOperator1() { diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 158e4d334..a28765767 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -381,7 +381,8 @@ private: // Tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); - tokenizer.tokenize(istr, filename); + if (!tokenizer.tokenize(istr, filename)) + return; // Check for unused variables.. CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this);