From 001d38261484b043b32cbbfa23dd36a00c5efa75 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Wed, 26 Jan 2011 23:44:15 +0200 Subject: [PATCH 1/7] GUI: Enable warnings about missing include files. --- gui/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 75a3f54b2..72cd10091 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -358,6 +358,7 @@ Settings MainWindow::GetCppcheckSettings() result.addEnabled("style"); result.addEnabled("information"); + result.addEnabled("missingInclude"); result.debug = false; result.debugwarnings = mSettings->value(SETTINGS_SHOW_DEBUG_WARNINGS, false).toBool(); result._errorsOnly = false; From 50dba88077814d643ca2a8654c256915b9613e94 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 08:47:28 +0200 Subject: [PATCH 2/7] Fix formatting of debug messages to log view. Ticket #2513 (GUI: Garbage printed to log after missing include warning) The linenumber was not properly converted to the QString so there were garbage printed to the log. --- gui/erroritem.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gui/erroritem.cpp b/gui/erroritem.cpp index 35506c697..a7b09c853 100644 --- a/gui/erroritem.cpp +++ b/gui/erroritem.cpp @@ -43,9 +43,11 @@ ErrorItem::ErrorItem(const ErrorLine &line) QString ErrorItem::ToString() const { QString str = file + " - " + id + " - " + severity +"\n"; - str += " " + summary; - str += "\n" + message; + str += summary + "\n"; + str += message + "\n"; for (int i = 0; i < files.size(); i++) - str += " " + files[i] + ": " + lines[i] + "\n"; + { + str += " " + files[i] + ": " + QString::number(lines[i]) + "\n"; + } return str; } From dcc241a2b46caad2c8da57fc2c5527ca1704cd69 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 10:30:53 +0200 Subject: [PATCH 3/7] Don't print "files not found" after showing help. Fix ticket #2496 (Is error reporting for an unneeded parameter wrong?) There are several command line options / commands after which we don't want Cppcheck to even try to open any files. Eg. printing help or listing errors. So add new attribute for CmdLineParser to track use of these options and exit before checking files when the attribute is set. --- cli/cmdlineparser.cpp | 5 +++++ cli/cmdlineparser.h | 9 +++++++++ cli/cppcheckexecutor.cpp | 4 +++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index af6e677af..0d9ded344 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -60,6 +60,7 @@ CmdLineParser::CmdLineParser(Settings *settings) , _showHelp(false) , _showVersion(false) , _showErrorMessages(false) + , _exitAfterPrint(false) { } @@ -75,6 +76,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) if (strcmp(argv[i], "--version") == 0) { _showVersion = true; + _exitAfterPrint = true; return true; } // Flag used for various purposes during debugging @@ -365,6 +367,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) //_cppcheck->getErrorMessages(); _showErrorMessages = true; _settings->_xml = true; + _exitAfterPrint = true; return true; } @@ -383,6 +386,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) while (doc2.find("\n\n\n") != std::string::npos) doc2.erase(doc2.find("\n\n\n"), 1); std::cout << doc2; + _exitAfterPrint = true; return true; } @@ -459,6 +463,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) { _pathnames.clear(); _showHelp = true; + _exitAfterPrint = true; break; } diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 60fccb93b..7a60e24a6 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -84,6 +84,14 @@ public: return _showHelp; } + /** + * Return if we should exit after printing version, help etc. + */ + bool ExitAfterPrinting() const + { + return _exitAfterPrint; + } + protected: /** @@ -101,6 +109,7 @@ private: bool _showHelp; bool _showVersion; bool _showErrorMessages; + bool _exitAfterPrint; std::vector _pathnames; }; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 4885357e6..efc6ceadc 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -57,8 +57,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version); cppcheck->getErrorMessages(); std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl; - std::exit(0); } + + if (parser.ExitAfterPrinting()) + std::exit(0); } // Check that all include paths exist From a794edd93461b521f8255d989061b3a96b065d19 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 11:14:08 +0200 Subject: [PATCH 4/7] Don't stop processing cmd line after --errorlist. Ticket #2441 (Parsing of command line arguments breaks after --errorlist) Instead of stopping processing command line options after --errorlist process them all. This way e.g. --verbose can be given also after the --errorlist. --- cli/cmdlineparser.cpp | 8 ++++---- cli/cppcheckexecutor.cpp | 3 +-- test/testcmdlineparser.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0d9ded344..f4a80138f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -364,11 +364,9 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) // print all possible error messages.. else if (strcmp(argv[i], "--errorlist") == 0) { - //_cppcheck->getErrorMessages(); _showErrorMessages = true; _settings->_xml = true; _exitAfterPrint = true; - return true; } // documentation.. @@ -491,15 +489,17 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) PrintMessage("--test-2-pass doesn't work with -j option yet."); } - if (argc <= 1) _showHelp = true; if (_showHelp) { PrintHelp(); + return true; } - else if (_pathnames.empty()) + + // Print error only if we have "real" command and expect files + if (!_exitAfterPrint && _pathnames.empty()) { PrintMessage("cppcheck: No C or C++ source files found."); return false; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index efc6ceadc..fdb886471 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -45,10 +45,9 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (success) { - if (parser.GetShowVersion()) + if (parser.GetShowVersion() && !parser.GetShowErrorMessages()) { std::cout << "Cppcheck " << cppcheck->version() << std::endl; - return true; } if (parser.GetShowErrorMessages()) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index a0a29cbd6..3c2599c9a 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -77,6 +77,9 @@ private: TEST_CASE(templatesGcc); TEST_CASE(templatesVs); TEST_CASE(xml); + TEST_CASE(errorlist1); + TEST_CASE(errorlistverbose1) + TEST_CASE(errorlistverbose2) TEST_CASE(unknownParam); } @@ -535,6 +538,35 @@ private: ASSERT(settings._xml); } + void errorlist1() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--errorlist"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(2, argv)); + } + + void errorlistverbose1() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--verbose", "--errorlist"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._verbose); + } + + void errorlistverbose2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--errorlist", "--verbose"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._verbose); + } + void unknownParam() { REDIRECT; From 97f041f292305844cc744b080fde1b0bebea13d1 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 13:14:53 +0200 Subject: [PATCH 5/7] GUI: Update homepage URL to About-dialog. --- gui/aboutdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/aboutdialog.cpp b/gui/aboutdialog.cpp index f21bc5495..ec79fc6bf 100644 --- a/gui/aboutdialog.cpp +++ b/gui/aboutdialog.cpp @@ -27,7 +27,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) mUI.setupUi(this); mUI.mVersion->setText(mUI.mVersion->text().arg(version)); - QString url = "http://cppcheck.wiki.sourceforge.net/"; + QString url = "http://cppcheck.sourceforge.net/"; mUI.mHomepage->setText(mUI.mHomepage->text().arg(url)); connect(mUI.mButtons, SIGNAL(accepted()), this, SLOT(accept())); } From 090436ea9581b8652a7b3d30f046d691e0b6b693 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 14:25:10 +0200 Subject: [PATCH 6/7] Add cmd line parser tests for XML ver 2 options. --- test/testcmdlineparser.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 3c2599c9a..78dc5be51 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -77,6 +77,9 @@ private: TEST_CASE(templatesGcc); TEST_CASE(templatesVs); TEST_CASE(xml); + TEST_CASE(xmlver2); + TEST_CASE(xmlver2both); + TEST_CASE(xmlver2both2); TEST_CASE(errorlist1); TEST_CASE(errorlistverbose1) TEST_CASE(errorlistverbose2) @@ -536,6 +539,40 @@ private: CmdLineParser parser(&settings); ASSERT(parser.ParseFromArgs(3, argv)); ASSERT(settings._xml); + ASSERT_EQUALS(1, settings._xml_version); + } + + void xmlver2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml-version=2", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); + } + + void xmlver2both() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml", "--xml-version=2", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); + } + + void xmlver2both2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml-version=2", "--xml", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); } void errorlist1() From 524498e439b988e1c13a917b4ff59f5a6b797324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 27 Jan 2011 18:44:20 +0100 Subject: [PATCH 7/7] Tokenizer: collapse operator function names into a single token. ticket: #2519 --- lib/checkclass.cpp | 29 +++++++------------- lib/symboldatabase.cpp | 53 ++++--------------------------------- lib/tokenize.cpp | 33 ++++++++++++++++++++++- lib/tokenize.h | 6 +++++ test/testclass.cpp | 2 +- test/testsimplifytokens.cpp | 14 +++++----- test/testtokenize.cpp | 40 +++++++++++++++++++++++++--- test/testunusedprivfunc.cpp | 3 +-- 8 files changed, 99 insertions(+), 81 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 2881d894b..fc96af0cc 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -140,11 +140,7 @@ void CheckClass::constructors() // It's non-static and it's not initialized => error if (func->type == Function::eOperatorEqual) { - const Token *operStart = 0; - if (func->token->str() == "=") - operStart = func->token->tokAt(1); - else - operStart = func->token->tokAt(3); + const Token *operStart = func->token->tokAt(1); bool classNameUsed = false; for (const Token *operTok = operStart; operTok != operStart->link(); operTok = operTok->next()) @@ -376,14 +372,14 @@ void CheckClass::initializeVarList(const Function &func, std::list } // Calling member function? - else if (Token::simpleMatch(ftok, "operator = (") && + else if (Token::simpleMatch(ftok, "operator= (") && ftok->previous()->str() != "::") { // check if member function exists std::list::const_iterator it; for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - if (ftok->next()->str() == it->tokenDef->str() && it->type != Function::eConstructor) + if (ftok->str() == it->tokenDef->str() && it->type != Function::eConstructor) break; } @@ -583,11 +579,6 @@ void CheckClass::privateFunctions() if (Token::findmatch(_tokenizer->tokens(), "; __property ;")) return; - // #2407 calls from operator() is not detected - // TODO: Don't bailout. Detect the call. - if (Token::findmatch(_tokenizer->tokens(), "operator ( )")) - return; - createSymbolDatabase(); std::list::const_iterator i; @@ -872,8 +863,8 @@ void CheckClass::operatorEq() { if (it->type == Function::eOperatorEqual && it->access != Private) { - if (it->token->strAt(-2) == "void") - operatorEqReturnError(it->token->tokAt(-2)); + if (it->token->strAt(-1) == "void") + operatorEqReturnError(it->token->tokAt(-1)); } } } @@ -940,7 +931,7 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co // check of *this is returned else if (!(Token::Match(tok->tokAt(1), "(| * this ;|=") || Token::Match(tok->tokAt(1), "(| * this +=") || - Token::Match(tok->tokAt(1), "operator = ("))) + Token::Match(tok->tokAt(1), "operator= ("))) operatorEqRetRefThisError(func->token); } } @@ -971,8 +962,8 @@ void CheckClass::operatorEqRetRefThis() if (func->type == Function::eOperatorEqual && func->hasBody) { // make sure return signature is correct - if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - func->tokenDef->strAt(-3) == scope->className) + if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && + func->tokenDef->strAt(-2) == scope->className) { // find the ')' const Token *tok = func->token->next()->link(); @@ -1027,8 +1018,8 @@ void CheckClass::operatorEqToSelf() if (it->type == Function::eOperatorEqual && it->hasBody) { // make sure return signature is correct - if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - it->tokenDef->strAt(-3) == scope->className) + if (Token::Match(it->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && + it->tokenDef->strAt(-2) == scope->className) { // check for proper function parameter signature if ((Token::Match(it->tokenDef->next(), "( const %var% & )") || diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 08c8d5486..8b7947387 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -137,12 +137,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.tokenDef = funcStart; // operator function - if (function.tokenDef->previous()->str() == "operator") + if (function.tokenDef->str().find("operator") == 0) { function.isOperator = true; // 'operator =' is special - if (function.tokenDef->str() == "=") + if (function.tokenDef->str() == "operator=") function.type = Function::eOperatorEqual; } @@ -578,38 +578,6 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const return true; } - // simple operator? - else if (Token::Match(tok, "operator %any% (") && Token::Match(tok->tokAt(2)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(2); - return true; - } - - // operator[] or operator()? - else if (Token::Match(tok, "operator %any% %any% (") && Token::Match(tok->tokAt(3)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(3); - return true; - } - - // operator new/delete []? - else if (Token::Match(tok, "operator %any% %any% %any% (") && Token::Match(tok->tokAt(4)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(4); - return true; - } - - // complex user defined operator? - else if (Token::Match(tok, "operator %any% %any% %any% %any% (") && Token::Match(tok->tokAt(5)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(5); - return true; - } - return false; } @@ -772,20 +740,9 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * { if (!func->hasBody) { - if (func->isOperator && - (*tok)->str() == "operator" && - func->tokenDef->str() == (*tok)->strAt(1)) - { - if (argsMatch(scope1, func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length)) - { - func->hasBody = true; - func->token = (*tok)->next(); - func->arg = argStart; - } - } - else if (func->type == Function::eDestructor && - (*tok)->previous()->str() == "~" && - func->tokenDef->str() == (*tok)->str()) + if (func->type == Function::eDestructor && + (*tok)->previous()->str() == "~" && + func->tokenDef->str() == (*tok)->str()) { if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ee640937a..d21484c52 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -513,7 +513,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name) } else if (end->str() == "(") { - if (tok->previous()->str() == "operator") + if (tok->previous()->str().find("operator") == 0) { // conversion operator return false; @@ -2490,6 +2490,10 @@ bool Tokenizer::tokenize(std::istream &code, // remove exception specifications.. removeExceptionSpecifications(_tokens); + // Collapse operator name tokens into single token + // operator = => operator= + simplifyOperatorName(); + // simplify function pointers simplifyFunctionPointers(); @@ -9238,3 +9242,30 @@ const SymbolDatabase *Tokenizer::getSymbolDatabase() const return _symbolDatabase; } + +void Tokenizer::simplifyOperatorName() +{ + for (const Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, ") const| {|;|=")) + { + Token *tok1 = tok->link(); + Token *tok2 = tok1; + + tok1 = tok1->previous(); + while (tok1 && !Token::Match(tok1, "operator|{|}|;|public:|private|protected:")) + { + tok1 = tok1->previous(); + } + + if (tok1 && tok1->str() == "operator") + { + while (tok1->next() != tok2) + { + tok1->str(tok1->str() + tok1->next()->str()); + tok1->deleteNext(); + } + } + } + } +} diff --git a/lib/tokenize.h b/lib/tokenize.h index 318bdf4c4..8dacc345a 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -531,6 +531,12 @@ public: */ void simplifyQtSignalsSlots(); + /** + * Collapse operator name tokens into single token + * operator = => operator= + */ + void simplifyOperatorName(); + /** * This will return a short name describing function parameters * e.g. parameters: (int a, char b) should get name "int,char,". diff --git a/test/testclass.cpp b/test/testclass.cpp index 431c7252e..44ffed8a3 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -3506,7 +3506,7 @@ private: " typedef int* (Fred::*UnspecifiedBoolType);\n" " operator UnspecifiedBoolType() { };\n" "};\n"); - ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'Fred::int' can be const.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'Fred::operatorint**' can be const.\n", errout.str()); checkConst("struct Fred {\n" " int array[10];\n" diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index f41f58c51..8f29e3efb 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -382,8 +382,8 @@ private: ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)")); ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)")); ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)")); - ASSERT_EQUALS("class A { A operator * ( int ) ; } ;", tok("class A { A operator *(int); };")); - ASSERT_EQUALS("class A { A operator * ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); + ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };")); + ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)(char *)0)")); } @@ -2578,7 +2578,7 @@ private: { // Ticket #1997 const char code[] = "void * operator new[](size_t);"; - ASSERT_EQUALS("void * operator new [ ] ( size_t ) ;", tok(code)); + ASSERT_EQUALS("void * operatornew[] ( size_t ) ;", tok(code)); } ASSERT_EQUALS("; a [ 0 ] ;", tok(";a[0*(*p)];")); @@ -4429,7 +4429,7 @@ private: const std::string expected("struct C { " "; " "const void * pr ; " // this gets simplified to a regular pointer - "operator const void ( * ) ( ) & ( ) { return pr ; } " + "operatorconstvoid(*)()& ( ) { return pr ; } " "} ;"); ASSERT_EQUALS(expected, sizeof_(code)); @@ -4713,7 +4713,7 @@ private: "};\n"; const std::string expected = "class Fred { " "; " - "operator int * * ( ) const { } " + "operatorint** ( ) const { } " "} ;"; ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS("", errout.str()); @@ -4755,9 +4755,9 @@ private: "Fred::operator F() const { }\n"; const std::string expected = "class Fred { " "; " - "operator int * * ( ) const ; " + "operatorint** ( ) const ; " "} ; " - "Fred :: operator int * * ( ) const { }"; + "Fred :: operatorint** ( ) const { }"; ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS("", errout.str()); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index dfa87d3bb..561b91a95 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -293,6 +293,8 @@ private: // Tokenize JAVA TEST_CASE(java); + + TEST_CASE(simplifyOperatorName); } @@ -2990,7 +2992,7 @@ private: "1: class Foo\n" "2: {\n" "3: public:\n" - "4: void operator = ( const Foo & ) ;\n" + "4: void operator= ( const Foo & ) ;\n" "5: } ;\n"); ASSERT_EQUALS(expected, actual); @@ -3002,7 +3004,7 @@ private: "};\n"); const std::string expected("\n\n##file 0\n" "1: struct Foo {\n" - "2: void * operator new [ ] ( int ) ;\n" + "2: void * operatornew[] ( int ) ;\n" "3: } ;\n"); ASSERT_EQUALS(expected, actual); @@ -3660,7 +3662,7 @@ private: const std::string actual(tokenizeAndStringify(code)); const char expected[] = "struct foo {\n" - "void operator delete ( void * obj , size_t sz ) ;\n" + "void operatordelete ( void * obj , size_t sz ) ;\n" "}"; ASSERT_EQUALS(expected, actual); @@ -5182,6 +5184,38 @@ private: { ASSERT_EQUALS("void f ( ) { }", javatest("void f() throws Exception { }")); } + + void simplifyOperatorName() + { + // make sure C code doesn't get changed + const char code1[] = "void operator () {}" + "int main()" + "{" + " operator();" + "}"; + + const char result1 [] = "void operator ( ) { } " + "int main ( ) " + "{ " + "operator ( ) ; " + "}"; + + ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false)); + + const char code2[] = "class Fred" + "{" + " Fred(const Fred & f) { operator = (f); }" + " operator = ();" + "}"; + + const char result2 [] = "class Fred " + "{ " + "Fred ( const Fred & f ) { operator= ( f ) ; } " + "operator= ( ) ; " + "}"; + + ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false)); + } }; REGISTER_TEST(TestTokenizer) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index ff6f84c60..adbbf2b20 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -460,8 +460,7 @@ private: " void startListening() {\n" " }\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); } void testDoesNotIdentifyMethodAsFirstFunctionArgument()