diff --git a/Makefile b/Makefile index 50fd73343..fc9126b5b 100644 --- a/Makefile +++ b/Makefile @@ -694,7 +694,7 @@ test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/color.h lib/c test/testboost.o: test/testboost.cpp lib/check.h lib/checkboost.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testboost.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h @@ -703,7 +703,7 @@ test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color. test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclass.o: test/testclass.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h @@ -730,7 +730,7 @@ test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/ test/testfunctions.o: test/testfunctions.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testgarbage.o: test/testgarbage.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 1f6debe2f..f2e50e346 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -147,13 +147,13 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c #else const bool caseSensitive = true; #endif - if (!mSettings->project.fileSettings.empty() && !mSettings->fileFilters.empty()) { + if (!settings.project.fileSettings.empty() && !settings.fileFilters.empty()) { // filter only for the selected filenames from all project files std::list newList; const std::list& fileSettings = settings.project.fileSettings; std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(newList), [&](const ImportProject::FileSettings& fs) { - return matchglobs(mSettings->fileFilters, fs.filename); + return matchglobs(settings.fileFilters, fs.filename); }); if (!newList.empty()) settings.project.fileSettings = newList; @@ -165,7 +165,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c // Execute recursiveAddFiles() to each given file parameter const PathMatch matcher(ignored, caseSensitive); for (const std::string &pathname : pathnames) { - std::string err = FileLister::recursiveAddFiles(mFiles, Path::toNativeSeparators(pathname), mSettings->library.markupExtensions(), matcher); + std::string err = FileLister::recursiveAddFiles(mFiles, Path::toNativeSeparators(pathname), settings.library.markupExtensions(), matcher); if (!err.empty()) { std::cout << "cppcheck: " << err << std::endl; } @@ -177,10 +177,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (!ignored.empty()) std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl; return false; - } else if (!mSettings->fileFilters.empty() && settings.project.fileSettings.empty()) { + } else if (!settings.fileFilters.empty() && settings.project.fileSettings.empty()) { std::map newMap; for (std::map::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) - if (matchglobs(mSettings->fileFilters, i->first)) { + if (matchglobs(settings.fileFilters, i->first)) { newMap[i->first] = i->second; } mFiles = newMap; @@ -226,11 +226,6 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) return ret; } -void CppCheckExecutor::setSettings(const Settings &settings) -{ - mSettings = &settings; -} - int CppCheckExecutor::check_wrapper(CppCheck& cppcheck) { #ifdef USE_WINDOWS_SEH @@ -266,7 +261,6 @@ bool CppCheckExecutor::reportSuppressions(const Settings &settings, bool unusedF int CppCheckExecutor::check_internal(CppCheck& cppcheck) { Settings& settings = cppcheck.settings(); - mSettings = &settings; const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg"); for (const std::string &lib : settings.libraries) { @@ -330,8 +324,8 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) unsigned int c = 0; if (settings.project.fileSettings.empty()) { for (std::map::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { - if (!mSettings->library.markupFile(i->first) - || !mSettings->library.processMarkupAfterCode(i->first)) { + if (!settings.library.markupFile(i->first) + || !settings.library.processMarkupAfterCode(i->first)) { returnValue += cppcheck.check(i->first); processedsize += i->second; if (!settings.quiet) @@ -355,7 +349,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) // second loop to parse all markup files which may not work until all // c/cpp files have been parsed and checked for (std::map::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { - if (mSettings->library.markupFile(i->first) && mSettings->library.processMarkupAfterCode(i->first)) { + if (settings.library.markupFile(i->first) && settings.library.processMarkupAfterCode(i->first)) { returnValue += cppcheck.check(i->first); processedsize += i->second; if (!settings.quiet) @@ -374,7 +368,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) returnValue = executor.check(); } - cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles); + cppcheck.analyseWholeProgram(settings.buildDir, mFiles); if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) { const bool err = reportSuppressions(settings, cppcheck.isUnusedFunctionCheckEnabled(), mFiles, *this); @@ -413,7 +407,6 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) reportErr(ErrorMessage::getXMLFooter()); } - mSettings = nullptr; if (returnValue) return settings.exitCode; return 0; diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index e52ed62d4..e96acde34 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -137,12 +137,6 @@ protected: */ bool parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[]); - /** - * Helper function to supply settings. This can be used for testing. - * @param settings Reference to an Settings instance - */ - void setSettings(const Settings &settings); - private: /** @@ -166,7 +160,7 @@ private: int check_internal(CppCheck& cppcheck); /** - * Pointer to current settings; set while check() is running. + * Pointer to current settings; set while check() is running for reportError(). */ const Settings* mSettings; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index dae0974f5..212e9c56a 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -800,10 +800,10 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string } // Run define rules on raw code - for (const Settings::Rule &rule : mSettings.rules) { - if (rule.tokenlist != "define") - continue; - + const auto it = std::find_if(mSettings.rules.cbegin(), mSettings.rules.cend(), [](const Settings::Rule& rule) { + return rule.tokenlist == "define"; + }); + if (it != mSettings.rules.cend()) { std::string code; const std::list &directives = preprocessor.getDirectives(); for (const Directive &dir : directives) { @@ -814,7 +814,6 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string std::istringstream istr2(code); tokenizer2.list.createTokens(istr2); executeRules("define", tokenizer2); - break; } if (!mSettings.force && configurations.size() > mSettings.maxConfigs) { @@ -871,8 +870,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string continue; } - Tokenizer tokenizer(&mSettings, this); - tokenizer.setPreprocessor(&preprocessor); + Tokenizer tokenizer(&mSettings, this, &preprocessor); if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) tokenizer.setTimerResults(&s_timerResults); diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 0932db71a..fb6db23fe 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -588,7 +588,7 @@ namespace { // TODO : Better evaluation Settings s; std::istringstream istr(c); - Tokenizer tokenizer(&s, nullptr); + Tokenizer tokenizer(&s); tokenizer.tokenize(istr,"vcxproj"); for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { if (tok->str() == "(" && tok->astOperand1() && tok->astOperand2()) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2bcaaca95..e5839c954 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -155,35 +155,20 @@ static bool isClassStructUnionEnumStart(const Token * tok) //--------------------------------------------------------------------------- -Tokenizer::Tokenizer() : - list(nullptr), - mSettings(nullptr), - mErrorLogger(nullptr), - mSymbolDatabase(nullptr), - mTemplateSimplifier(nullptr), - mVarId(0), - mUnnamedCount(0), - mCodeWithTemplates(false), //is there any templates? - mTimerResults(nullptr), - mPreprocessor(nullptr) -{} - -Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger) : +Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger, const Preprocessor *preprocessor) : list(settings), mSettings(settings), mErrorLogger(errorLogger), mSymbolDatabase(nullptr), - mTemplateSimplifier(nullptr), + mTemplateSimplifier(new TemplateSimplifier(this)), mVarId(0), mUnnamedCount(0), mCodeWithTemplates(false), //is there any templates? mTimerResults(nullptr), - mPreprocessor(nullptr) + mPreprocessor(preprocessor) { // make sure settings are specified assert(mSettings); - - mTemplateSimplifier = new TemplateSimplifier(this); } Tokenizer::~Tokenizer() @@ -2773,16 +2758,11 @@ bool Tokenizer::simplifyUsing() bool Tokenizer::createTokens(std::istream &code, const std::string& FileName) { - // make sure settings specified - assert(mSettings); - return list.createTokens(code, FileName); } void Tokenizer::createTokens(simplecpp::TokenList&& tokenList) { - // make sure settings specified - assert(mSettings); list.createTokens(std::move(tokenList)); } @@ -9811,8 +9791,8 @@ void Tokenizer::simplifyNamespaceAliases() bool Tokenizer::hasIfdef(const Token *start, const Token *end) const { - if (!mPreprocessor) - return false; + assert(mPreprocessor); + return std::any_of(mPreprocessor->getDirectives().cbegin(), mPreprocessor->getDirectives().cend(), [&](const Directive& d) { return d.str.compare(0, 3, "#if") == 0 && d.linenr >= start->linenr() && diff --git a/lib/tokenize.h b/lib/tokenize.h index 5d3e235f4..43a754b56 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -25,6 +25,7 @@ #include "errortypes.h" #include "tokenlist.h" +#include #include #include #include @@ -59,8 +60,7 @@ class CPPCHECKLIB Tokenizer { friend class TemplateSimplifier; public: - Tokenizer(); - Tokenizer(const Settings * settings, ErrorLogger *errorLogger); + explicit Tokenizer(const Settings * settings, ErrorLogger *errorLogger = nullptr, const Preprocessor *preprocessor = nullptr); ~Tokenizer(); void setTimerResults(TimerResults *tr) { @@ -377,10 +377,8 @@ public: */ static const Token * isFunctionHead(const Token *tok, const std::string &endsWith, bool cpp); - void setPreprocessor(const Preprocessor *preprocessor) { - mPreprocessor = preprocessor; - } const Preprocessor *getPreprocessor() const { + assert(mPreprocessor); return mPreprocessor; } @@ -621,12 +619,6 @@ public: return mCodeWithTemplates; } - - void setSettings(const Settings *settings) { - mSettings = settings; - list.setSettings(settings); - } - const SymbolDatabase *getSymbolDatabase() const { return mSymbolDatabase; } @@ -703,7 +695,7 @@ private: void setPodTypes(); /** settings */ - const Settings * mSettings; + const Settings * const mSettings; /** errorlogger */ ErrorLogger* const mErrorLogger; @@ -711,7 +703,7 @@ private: /** Symbol database that all checks etc can use */ SymbolDatabase *mSymbolDatabase; - TemplateSimplifier *mTemplateSimplifier; + TemplateSimplifier * const mTemplateSimplifier; /** E.g. "A" for code where "#ifdef A" is true. This is used to print additional information in error situations. */ @@ -746,7 +738,7 @@ private: */ TimerResults *mTimerResults; - const Preprocessor *mPreprocessor; + const Preprocessor * const mPreprocessor; }; /// @} diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 7cddfd28e..4c98446a1 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -23,7 +23,6 @@ #include "errortypes.h" #include "standards.h" #include "library.h" -#include "preprocessor.h" #include "settings.h" #include "fixture.h" #include "tokenize.h" @@ -99,14 +98,10 @@ private: std::map filedata; simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); - Preprocessor preprocessor(*settings, nullptr); - preprocessor.setDirectives(tokens1); - // Tokenizer.. Tokenizer tokenizer(settings, this); tokenizer.createTokens(std::move(tokens2)); tokenizer.simplifyTokens1(""); - tokenizer.setPreprocessor(&preprocessor); // Check for buffer overruns.. runChecks(&tokenizer, settings, this); diff --git a/test/testclass.cpp b/test/testclass.cpp index 8f07f22c8..eccc6b252 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -20,6 +20,7 @@ #include "checkclass.h" #include "errortypes.h" #include "library.h" +#include "preprocessor.h" #include "settings.h" #include "fixture.h" #include "tokenize.h" @@ -260,8 +261,10 @@ private: Settings settings; settings.severity.enable(Severity::warning); + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -364,8 +367,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -516,8 +521,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings1, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings1, this); + Tokenizer tokenizer(&settings1, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -677,8 +684,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -1124,8 +1133,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -1598,8 +1609,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings1, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings1, this); + Tokenizer tokenizer(&settings1, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -2560,8 +2573,10 @@ private: settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings0.severity.enable(Severity::warning); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -2877,12 +2892,14 @@ private: checkNoMemset_(file, line, code, settings); } - void checkNoMemset_(const char* file, int line, const char code[], const Settings &settings) { + void checkNoMemset_(const char* file, int line, const char code[], Settings &settings) { // Clear the error log errout.str(""); + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -3512,8 +3529,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings1, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings1, this); + Tokenizer tokenizer(&settings1, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -3550,8 +3569,10 @@ private: s = &settings0; s->certainty.setEnabled(Certainty::inconclusive, inconclusive); + Preprocessor preprocessor(*s, nullptr); + // Tokenize.. - Tokenizer tokenizer(s, this); + Tokenizer tokenizer(s, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7060,8 +7081,10 @@ private: // Check.. settings0.certainty.setEnabled(Certainty::inconclusive, true); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7096,8 +7119,10 @@ private: Settings settings; settings.severity.enable(Severity::performance); + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7308,8 +7333,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings0, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings0, this); + Tokenizer tokenizer(&settings0, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7415,24 +7442,23 @@ private: #define checkVirtualFunctionCall(...) checkVirtualFunctionCall_(__FILE__, __LINE__, __VA_ARGS__) - void checkVirtualFunctionCall_(const char* file, int line, const char code[], Settings *s = nullptr, bool inconclusive = true) { + void checkVirtualFunctionCall_(const char* file, int line, const char code[], bool inconclusive = true) { // Clear the error log errout.str(""); // Check.. - if (!s) { - static Settings settings_; - s = &settings_; - s->severity.enable(Severity::warning); - } - s->certainty.setEnabled(Certainty::inconclusive, inconclusive); + Settings settings; + settings.severity.enable(Severity::warning); + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); + + Preprocessor preprocessor(settings, nullptr); // Tokenize.. - Tokenizer tokenizer(s, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); - CheckClass checkClass(&tokenizer, s, this); + CheckClass checkClass(&tokenizer, &settings, this); checkClass.checkVirtualFunctionCallInConstructor(); } @@ -7774,8 +7800,10 @@ private: Settings settings; settings.severity.enable(Severity::style); + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7950,8 +7978,10 @@ private: settings.safeChecks.classes = true; settings.severity.enable(Severity::warning); + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -7971,8 +8001,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings1, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings1, this); + Tokenizer tokenizer(&settings1, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); @@ -8168,8 +8200,10 @@ private: // Clear the error log errout.str(""); + Preprocessor preprocessor(settings1, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings1, this); + Tokenizer tokenizer(&settings1, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); diff --git a/test/testcondition.cpp b/test/testcondition.cpp index f6b261adc..f6a89ae20 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -160,10 +160,9 @@ private: preprocessor.setDirectives(tokens1); // Tokenizer.. - Tokenizer tokenizer(settings, this); + Tokenizer tokenizer(settings, this, &preprocessor); tokenizer.createTokens(std::move(tokens2)); tokenizer.simplifyTokens1(""); - tokenizer.setPreprocessor(&preprocessor); // Run checks.. runChecks(&tokenizer, settings, this); diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 0eeabec4f..e1a74d672 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -19,6 +19,7 @@ #include "check.h" #include "errortypes.h" #include "mathlib.h" +#include "preprocessor.h" #include "settings.h" #include "fixture.h" #include "token.h" @@ -286,8 +287,10 @@ private: std::string checkCodeInternal_(const std::string &code, const char* filename, const char* file, int line) { errout.str(""); + Preprocessor preprocessor(settings, nullptr); + // tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); diff --git a/test/testother.cpp b/test/testother.cpp index 51dd8d801..9a7f090d3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -306,8 +306,10 @@ private: settings->certainty.setEnabled(Certainty::experimental, experimental); settings->verbose = verbose; + Preprocessor preprocessor(*settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(settings, this); + Tokenizer tokenizer(settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, filename ? filename : "test.cpp"), file, line); @@ -349,17 +351,16 @@ private: preprocessor.setDirectives(tokens1); // Tokenizer.. - Tokenizer tokenizer(settings, this); + Tokenizer tokenizer(settings, this, &preprocessor); tokenizer.createTokens(std::move(tokens2)); tokenizer.simplifyTokens1(""); - tokenizer.setPreprocessor(&preprocessor); // Check.. runChecks(&tokenizer, settings, this); } void checkInterlockedDecrement(const char code[]) { - static Settings settings; + Settings settings; settings.platformType = Settings::Win32A; check(code, nullptr, false, false, true, false, &settings); @@ -1543,12 +1544,14 @@ private: // Clear the error buffer.. errout.str(""); - static Settings settings; + Settings settings; settings.severity.enable(Severity::style); settings.standards.cpp = Standards::CPP03; // #5560 + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizerCpp(&settings, this); + Tokenizer tokenizerCpp(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizerCpp.tokenize(istr, "test.cpp"), file, line); @@ -1749,10 +1752,12 @@ private: if (portability) settings.severity.enable(Severity::portability); settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); - settings.defaultSign = 's'; + + Preprocessor preprocessor(settings, nullptr); + // Tokenize.. - Tokenizer tokenizer(&settings, this); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 6cfafff15..84798ae29 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -64,7 +64,7 @@ public: simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI(), &outputList); if (errorLogger) { - static Settings settings; + Settings settings; Preprocessor p(settings, errorLogger); p.reportOutput(outputList, true); } diff --git a/test/testtype.cpp b/test/testtype.cpp index 7a4430b1c..ffccc4668 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -44,14 +44,10 @@ private: } #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) - void check_(const char* file, int line, const char code[], Settings* settings = nullptr, const char filename[] = "test.cpp", const std::string& standard = "c++11") { + void check_(const char* file, int line, const char code[], Settings* settings, const char filename[] = "test.cpp", const std::string& standard = "c++11") { // Clear the error buffer.. errout.str(""); - if (!settings) { - static Settings _settings; - settings = &_settings; - } settings->severity.enable(Severity::warning); settings->severity.enable(Severity::portability); settings->standards.setCPP(standard); @@ -66,6 +62,7 @@ private: } void checkTooBigShift_Unix32() { + Settings settings0; Settings settings; PLATFORM(settings, Settings::Unix32); @@ -166,7 +163,7 @@ private: // #7266: C++, shift in macro check("void f(unsigned int x) {\n" " UINFO(x << 1234);\n" - "}"); + "}", &settings0); ASSERT_EQUALS("", errout.str()); // #8640 @@ -176,7 +173,7 @@ private: " constexpr const int shift[1] = {32};\n" " constexpr const int ret = a << shift[0];\n" // shift too many bits " return ret;\n" - "}"); + "}", &settings0); ASSERT_EQUALS("[test.cpp:5]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n" "[test.cpp:5]: (error) Signed integer overflow for expression 'a< 32)\n" " return 0;\n" " return rm>> k;\n" - "}"); + "}", &settings0); ASSERT_EQUALS( "[test.cpp:4] -> [test.cpp:6]: (warning) Shifting signed 32-bit value by 31 bits is undefined behaviour. See condition at line 4.\n", errout.str()); @@ -199,7 +196,7 @@ private: " return 0;\n" " else\n" " return rm>> k;\n" - "}"); + "}", &settings0); ASSERT_EQUALS( "[test.cpp:4] -> [test.cpp:7]: (warning) Shifting signed 32-bit value by 31 bits is undefined behaviour. See condition at line 4.\n", errout.str()); @@ -211,20 +208,20 @@ private: " return 0;\n" " else\n" " return rm>> k;\n" - "}"); + "}", &settings0); ASSERT_EQUALS("", errout.str()); check("static long long f(int x, long long y) {\n" " if (x >= 64)\n" " return 0;\n" " return -(y << (x-1));\n" - "}"); + "}", &settings0); ASSERT_EQUALS("", errout.str()); check("bool f() {\n" " std::ofstream outfile;\n" " outfile << vec_points[0](0) << static_cast(d) << ' ';\n" - "}"); + "}", &settings0); ASSERT_EQUALS("", errout.str()); check("void f(unsigned b, int len, unsigned char rem) {\n" // #10773 @@ -235,7 +232,7 @@ private: " if (bits == 512)\n" " len -= 8;\n" " }\n" - "}\n"); + "}\n", &settings0); ASSERT_EQUALS("", errout.str()); } @@ -282,12 +279,13 @@ private: } void signConversion() { + Settings settings0; Settings settings; PLATFORM(settings, Settings::Unix64); - check("x = -4 * (unsigned)y;"); + check("x = -4 * (unsigned)y;", &settings0); ASSERT_EQUALS("[test.cpp:1]: (warning) Expression '-4' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); - check("x = (unsigned)y * -4;"); + check("x = (unsigned)y * -4;", &settings0); ASSERT_EQUALS("[test.cpp:1]: (warning) Expression '-4' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); check("unsigned int dostuff(int x) {\n" // x is signed @@ -299,7 +297,7 @@ private: check("unsigned int f1(signed int x, unsigned int y) {" // x is signed " return x * y;\n" "}\n" - "void f2() { f1(-4,4); }"); + "void f2() { f1(-4,4); }", &settings0); ASSERT_EQUALS( "[test.cpp:1]: (warning) Expression 'x' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); @@ -307,7 +305,7 @@ private: check("unsigned int f1(int x) {" " return x * 5U;\n" "}\n" - "void f2() { f1(-4); }"); + "void f2() { f1(-4); }", &settings0); ASSERT_EQUALS( "[test.cpp:1]: (warning) Expression 'x' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); @@ -315,19 +313,19 @@ private: check("unsigned int f1(int x) {" // #6168: FP for inner calculation " return 5U * (1234 - x);\n" // <- signed subtraction, x is not sign converted "}\n" - "void f2() { f1(-4); }"); + "void f2() { f1(-4); }", &settings0); ASSERT_EQUALS("", errout.str()); // Don't warn for + and - check("void f1(int x) {" " a = x + 5U;\n" "}\n" - "void f2() { f1(-4); }"); + "void f2() { f1(-4); }", &settings0); ASSERT_EQUALS("", errout.str()); check("size_t foo(size_t x) {\n" " return -2 * x;\n" - "}"); + "}", &settings0); ASSERT_EQUALS("[test.cpp:2]: (warning) Expression '-2' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); } @@ -390,42 +388,43 @@ private: } void checkFloatToIntegerOverflow() { - check("x = (int)1E100;"); + Settings settings; + check("x = (int)1E100;", &settings); ASSERT_EQUALS("[test.cpp:1]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("void f(void) {\n" " return (int)1E100;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("void f(void) {\n" " return (int)-1E100;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("void f(void) {\n" " return (short)1E6;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("void f(void) {\n" " return (unsigned char)256.0;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("void f(void) {\n" " return (unsigned char)255.5;\n" - "}"); + "}", &settings); ASSERT_EQUALS("", removeFloat(errout.str())); check("void f(void) {\n" " char c = 1234.5;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); check("char f(void) {\n" " return 1234.5;\n" - "}"); + "}", &settings); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); } }; diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 0d7a3ad2b..b1a66424a 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -256,8 +256,7 @@ private: preprocessor.setDirectives(*directives); // Tokenize.. - Tokenizer tokenizer(&settings, this); - tokenizer.setPreprocessor(&preprocessor); + Tokenizer tokenizer(&settings, this, &preprocessor); std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);