From 6e025243db95aac19e64fba61eb1862964e3b4c6 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 29 Mar 2025 07:51:41 +0100 Subject: [PATCH 1/2] Tokenizer: provide `TokenList` in constructor --- lib/cppcheck.cpp | 30 +++++++++++++++++------------- lib/tokenize.cpp | 7 ++++--- lib/tokenize.h | 2 +- lib/tokenlist.h | 2 ++ test/helpers.h | 10 +++++----- test/testclangimport.cpp | 7 +++++-- test/testsimplifytemplate.cpp | 27 +++++++++++++++------------ test/testsimplifytypedef.cpp | 33 +++++++++++++++++++-------------- test/testtokenize.cpp | 20 ++++++++++++-------- 9 files changed, 80 insertions(+), 58 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 29ab4b54fd7..88ca70079a5 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -715,8 +715,9 @@ unsigned int CppCheck::checkClang(const FileWithDetails &file) } try { - Tokenizer tokenizer(mSettings, mErrorLogger); - tokenizer.list.appendFileIfNew(file.spath()); + TokenList tokenlist{&mSettings}; + tokenlist.appendFileIfNew(file.spath()); + Tokenizer tokenizer(std::move(tokenlist), mSettings, mErrorLogger); std::istringstream ast(output2); clangimport::parseClangAstDump(tokenizer, ast); ValueFlow::setValues(tokenizer.list, @@ -902,10 +903,9 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string if (mUnusedFunctionsCheck && (mSettings.useSingleJob() || analyzerInformation)) { std::size_t hash = 0; - // this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined. - Tokenizer tokenizer(mSettings, mErrorLogger); + TokenList tokenlist{&mSettings}; // enforce the language since markup files are special and do not adhere to the enforced language - tokenizer.list.setLang(Standards::Language::C, true); + tokenlist.setLang(Standards::Language::C, true); if (fileStream) { std::vector files; simplecpp::TokenList tokens(*fileStream, files, file.spath()); @@ -913,7 +913,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string const Preprocessor preprocessor(mSettings, mErrorLogger); hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions); } - tokenizer.list.createTokens(std::move(tokens)); + tokenlist.createTokens(std::move(tokens)); } else { std::vector files; @@ -922,8 +922,10 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string const Preprocessor preprocessor(mSettings, mErrorLogger); hash = calculateHash(preprocessor, tokens, mSettings, mSuppressions); } - tokenizer.list.createTokens(std::move(tokens)); + tokenlist.createTokens(std::move(tokens)); } + // this is not a real source file - we just want to tokenize it. treat it as C anyways as the language needs to be determined. + Tokenizer tokenizer(std::move(tokenlist), mSettings, mErrorLogger); mUnusedFunctionsCheck->parseTokens(tokenizer, mSettings); if (analyzerInformation) { @@ -1123,19 +1125,21 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string continue; } - Tokenizer tokenizer(mSettings, mErrorLogger); - if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) - tokenizer.setTimerResults(&s_timerResults); - tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? + TokenList tokenlist{&mSettings}; try { // Create tokens, skip rest of iteration if failed Timer::run("Tokenizer::createTokens", mSettings.showtime, &s_timerResults, [&]() { simplecpp::TokenList tokensP = preprocessor.preprocess(tokens1, mCurrentConfig, files, true); - tokenizer.list.createTokens(std::move(tokensP)); + tokenlist.createTokens(std::move(tokensP)); }); hasValidConfig = true; + Tokenizer tokenizer(std::move(tokenlist), mSettings, mErrorLogger); + if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) + tokenizer.setTimerResults(&s_timerResults); + tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? + // locations macros mLogger->setLocationMacros(tokenizer.tokens(), files); @@ -1221,7 +1225,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string mLogger->setAnalyzerInfo(nullptr); return mLogger->exitcode(); } catch (const InternalError &e) { - ErrorMessage errmsg = ErrorMessage::fromInternalError(e, &tokenizer.list, file.spath()); + ErrorMessage errmsg = ErrorMessage::fromInternalError(e, &tokenlist, file.spath()); mErrorLogger.reportErr(errmsg); } } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 11a0bb066c4..9ac8f154aac 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -115,8 +115,8 @@ static bool isClassStructUnionEnumStart(const Token * tok) //--------------------------------------------------------------------------- -Tokenizer::Tokenizer(const Settings &settings, ErrorLogger &errorLogger) : - list(&settings), +Tokenizer::Tokenizer(TokenList tokenList, const Settings &settings, ErrorLogger &errorLogger) : + list(std::move(tokenList)), mSettings(settings), mErrorLogger(errorLogger), mTemplateSimplifier(new TemplateSimplifier(*this)) @@ -10969,7 +10969,8 @@ bool Tokenizer::isPacked(const Token * bodyStart) const void Tokenizer::getErrorMessages(ErrorLogger& errorLogger, const Settings& settings) { - Tokenizer tokenizer(settings, errorLogger); + TokenList tokenlist{&settings}; + Tokenizer tokenizer(std::move(tokenlist), settings, errorLogger); tokenizer.invalidConstFunctionTypeError(nullptr); // checkLibraryNoReturn tokenizer.unhandled_macro_class_x_y(nullptr, "", "", "", ""); diff --git a/lib/tokenize.h b/lib/tokenize.h index 2a79be00efb..7ac23869967 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -54,7 +54,7 @@ class CPPCHECKLIB Tokenizer { friend class TestTokenizer; public: - explicit Tokenizer(const Settings & settings, ErrorLogger &errorLogger); + Tokenizer(TokenList tokenList, const Settings & settings, ErrorLogger &errorLogger); ~Tokenizer(); void setTimerResults(TimerResults *tr) { diff --git a/lib/tokenlist.h b/lib/tokenlist.h index eb1e3a3b878..7f01ca20a75 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -57,6 +57,8 @@ class CPPCHECKLIB TokenList { TokenList(const TokenList &) = delete; TokenList &operator=(const TokenList &) = delete; + TokenList(TokenList&& other) NOEXCEPT = default; + /** @return the source file path. e.g. "file.cpp" */ const std::string& getSourceFilePath() const; diff --git a/test/helpers.h b/test/helpers.h index b27b1e1e0c0..00ef9262626 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -45,19 +45,19 @@ namespace tinyxml2 { class SimpleTokenizer : public Tokenizer { public: explicit SimpleTokenizer(ErrorLogger& errorlogger, bool cpp = true) - : Tokenizer{s_settings, errorlogger} + : Tokenizer{TokenList{&s_settings}, s_settings, errorlogger} { list.setLang(cpp ? Standards::Language::CPP : Standards::Language::C, true); } SimpleTokenizer(const Settings& settings, ErrorLogger& errorlogger, bool cpp = true) - : Tokenizer{settings, errorlogger} + : Tokenizer{TokenList{&settings}, settings, errorlogger} { list.setLang(cpp ? Standards::Language::CPP : Standards::Language::C, true); } SimpleTokenizer(const Settings& settings, ErrorLogger& errorlogger, const std::string& filename) - : Tokenizer{settings, errorlogger} + : Tokenizer{TokenList{&settings}, settings, errorlogger} { list.setLang(Path::identify(filename, false)); list.appendFileIfNew(filename); @@ -238,14 +238,14 @@ class SimpleTokenizer2 : public Tokenizer { public: template SimpleTokenizer2(const Settings &settings, ErrorLogger &errorlogger, const char (&code)[size], const std::string& file0) - : Tokenizer{settings, errorlogger} + : Tokenizer{TokenList{&settings}, settings, errorlogger} { preprocess(code, mFiles, file0, *this, errorlogger); } // TODO: get rid of this SimpleTokenizer2(const Settings &settings, ErrorLogger &errorlogger, const char code[], const std::string& file0) - : Tokenizer{settings, errorlogger} + : Tokenizer{TokenList{&settings}, settings, errorlogger} { preprocess(code, mFiles, file0, *this, errorlogger); } diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index be1dbd21613..c2434367cc2 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -139,7 +140,8 @@ class TestClangImport : public TestFixture { std::string parse(const char clang[]) { const Settings settings = settingsBuilder().clang().build(); - Tokenizer tokenizer(settings, *this); + TokenList tokenlist{&settings}; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); std::istringstream istr(clang); clangimport::parseClangAstDump(tokenizer, istr); if (!tokenizer.tokens()) { @@ -1059,7 +1061,8 @@ class TestClangImport : public TestFixture { #define GET_SYMBOL_DB(AST) \ const Settings settings = settingsBuilder().clang().platform(Platform::Type::Unix64).build(); \ - Tokenizer tokenizer(settings, *this); \ + TokenList tokenlist{&settings}; \ + Tokenizer tokenizer(std::move(tokenlist), settings, *this); \ { \ std::istringstream istr(AST); \ clangimport::parseClangAstDump(tokenizer, istr); \ diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index a1bd7189818..1fd45ce4239 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include class TestSimplifyTemplate : public TestFixture { @@ -5427,12 +5428,12 @@ class TestSimplifyTemplate : public TestFixture { } unsigned int templateParameters(const char code[]) { - Tokenizer tokenizer(settings, *this); - + TokenList tokenlist{&settings}; std::istringstream istr(code); - tokenizer.list.appendFileIfNew("test.cpp"); - if (!tokenizer.list.createTokens(istr, Path::identify("test.cpp", false))) + tokenlist.appendFileIfNew("test.cpp"); + if (!tokenlist.createTokens(istr, Path::identify("test.cpp", false))) return false; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); tokenizer.createLinks(); tokenizer.splitTemplateRightAngleBrackets(false); @@ -5496,12 +5497,13 @@ class TestSimplifyTemplate : public TestFixture { // Helper function to unit test TemplateSimplifier::getTemplateNamePosition int templateNamePositionHelper(const char code[], unsigned offset = 0) { - Tokenizer tokenizer(settings, *this); + TokenList tokenlist{&settings}; std::istringstream istr(code); - tokenizer.list.appendFileIfNew("test.cpp"); - if (!tokenizer.list.createTokens(istr, Path::identify("test.cpp", false))) + tokenlist.appendFileIfNew("test.cpp"); + if (!tokenlist.createTokens(istr, Path::identify("test.cpp", false))) return false; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); tokenizer.createLinks(); tokenizer.splitTemplateRightAngleBrackets(false); @@ -5568,11 +5570,11 @@ class TestSimplifyTemplate : public TestFixture { // Helper function to unit test TemplateSimplifier::findTemplateDeclarationEnd bool findTemplateDeclarationEndHelper(const char code[], const char pattern[], unsigned offset = 0) { - Tokenizer tokenizer(settings, *this); - + TokenList tokenlist{&settings}; std::istringstream istr(code); - if (!TokenListHelper::createTokens(tokenizer.list, istr, "test.cpp")) + if (!TokenListHelper::createTokens(tokenlist, istr, "test.cpp")) return false; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); tokenizer.createLinks(); tokenizer.splitTemplateRightAngleBrackets(false); @@ -5598,11 +5600,12 @@ class TestSimplifyTemplate : public TestFixture { // Helper function to unit test TemplateSimplifier::getTemplateParametersInDeclaration bool getTemplateParametersInDeclarationHelper(const char code[], const std::vector & params) { - Tokenizer tokenizer(settings, *this); + TokenList tokenlist{&settings}; std::istringstream istr(code); - if (!TokenListHelper::createTokens(tokenizer.list, istr, "test.cpp")) + if (!TokenListHelper::createTokens(tokenlist, istr, "test.cpp")) return false; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); tokenizer.createLinks(); tokenizer.splitTemplateRightAngleBrackets(false); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 00b3ee80643..5f79d19e946 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -28,6 +28,7 @@ #include #include #include +#include class TestSimplifyTypedef : public TestFixture { public: @@ -272,11 +273,11 @@ class TestSimplifyTypedef : public TestFixture { } std::string simplifyTypedef(const char code[]) { - Tokenizer tokenizer(settings1, *this); - + TokenList tokenlist{&settings1}; std::istringstream istr(code); - if (!tokenizer.list.createTokens(istr, Standards::Language::CPP)) + if (!tokenlist.createTokens(istr, Standards::Language::CPP)) return ""; + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); @@ -306,11 +307,12 @@ class TestSimplifyTypedef : public TestFixture { std::string simplifyTypedefC(const char code[]) { - Tokenizer tokenizer(settings1, *this); + TokenList tokenlist{&settings1}; std::istringstream istr(code); - if (!TokenListHelper::createTokens(tokenizer.list, istr, "file.c")) + if (!TokenListHelper::createTokens(tokenlist, istr, "file.c")) return ""; + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); try { @@ -322,11 +324,11 @@ class TestSimplifyTypedef : public TestFixture { } std::string dumpTypedefInfo(const char code[]) { - Tokenizer tokenizer(settings1, *this); - + TokenList tokenlist{&settings1}; std::istringstream istr(code); - if (!TokenListHelper::createTokens(tokenizer.list, istr, "file.c")) + if (!TokenListHelper::createTokens(tokenlist, istr, "file.c")) return {}; + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); try { @@ -4451,9 +4453,10 @@ class TestSimplifyTypedef : public TestFixture { "uint8_t t;" "void test(rFunctionPointer_fp functionPointer);"; - Tokenizer tokenizer(settings1, *this); + TokenList tokenlist{&settings1}; std::istringstream istr(code); - ASSERT(TokenListHelper::createTokens(tokenizer.list, istr, "file.c")); + ASSERT(TokenListHelper::createTokens(tokenlist, istr, "file.c")); + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); @@ -4493,9 +4496,10 @@ class TestSimplifyTypedef : public TestFixture { " MY_INT x = 0;\n" "}"; - Tokenizer tokenizer(settings1, *this); + TokenList tokenlist{&settings1}; std::istringstream istr(code); - ASSERT(TokenListHelper::createTokens(tokenizer.list, istr, "file.c")); + ASSERT(TokenListHelper::createTokens(tokenlist, istr, "file.c")); + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); @@ -4511,9 +4515,10 @@ class TestSimplifyTypedef : public TestFixture { " F x = 0;\n" "}"; - Tokenizer tokenizer(settings1, *this); + TokenList tokenlist{&settings1}; std::istringstream istr(code); - ASSERT(TokenListHelper::createTokens(tokenizer.list, istr, "file.c")); + ASSERT(TokenListHelper::createTokens(tokenlist, istr, "file.c")); + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); tokenizer.createLinks(); tokenizer.simplifyTypedef(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 9c638348c4c..fa99095aa29 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -558,7 +558,8 @@ class TestTokenizer : public TestFixture { const simplecpp::TokenList tokens1(istr, files, filename, &outputList); std::list directives = preprocessor.createDirectives(tokens1); - Tokenizer tokenizer(settings, *this); + TokenList tokenlist{&settings}; + Tokenizer tokenizer(std::move(tokenlist), settings, *this); tokenizer.setDirectives(std::move(directives)); tokenizer.dump(ostr); @@ -865,11 +866,12 @@ class TestTokenizer : public TestFixture { ASSERT_THROW_INTERNAL(tokenizeAndStringify(";template class X { };",false,Platform::Type::Native,false), SYNTAX); ASSERT_THROW_INTERNAL(tokenizeAndStringify("int X() {};",false,Platform::Type::Native,false), SYNTAX); { - Tokenizer tokenizer(settings1, *this); + TokenList tokenlist{&settings1}; const char code[] = "void foo(int i) { reinterpret_cast(i) };"; std::istringstream istr(code); - tokenizer.list.appendFileIfNew("test.h"); - ASSERT(tokenizer.list.createTokens(istr, Path::identify("test.h", false))); + tokenlist.appendFileIfNew("test.h"); + ASSERT(tokenlist.createTokens(istr, Path::identify("test.h", false))); + Tokenizer tokenizer(std::move(tokenlist), settings1, *this); ASSERT_THROW_INTERNAL(tokenizer.simplifyTokens1(""), SYNTAX); } } @@ -3687,7 +3689,8 @@ class TestTokenizer : public TestFixture { } void simplifyString() { - Tokenizer tokenizer(settings0, *this); + TokenList tokenlist{&settings0}; + Tokenizer tokenizer(std::move(tokenlist), settings0, *this); ASSERT_EQUALS("\"abc\"", tokenizer.simplifyString("\"abc\"")); ASSERT_EQUALS("\"\n\"", tokenizer.simplifyString("\"\\xa\"")); ASSERT_EQUALS("\"3\"", tokenizer.simplifyString("\"\\x33\"")); @@ -6135,12 +6138,13 @@ class TestTokenizer : public TestFixture { std::string testAst(const char code[], AstStyle style = AstStyle::Simple) { // tokenize given code.. - Tokenizer tokenizer(settings0, *this); + TokenList tokenlist{&settings0}; std::istringstream istr(code); - tokenizer.list.appendFileIfNew("test.cpp"); - if (!tokenizer.list.createTokens(istr,Path::identify("test.cpp", false))) + tokenlist.appendFileIfNew("test.cpp"); + if (!tokenlist.createTokens(istr,Path::identify("test.cpp", false))) return "ERROR"; + Tokenizer tokenizer(std::move(tokenlist), settings0, *this); tokenizer.combineStringAndCharLiterals(); tokenizer.combineOperators(); tokenizer.simplifySpaceshipOperator(); From fcb91c005ea8bbe303ce4b04aa6814a3d039bed9 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 15 Apr 2025 11:40:31 +0200 Subject: [PATCH 2/2] CppCheck: adjusted scope and errorhandling in `checkFile()` --- lib/cppcheck.cpp | 109 +++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 88ca70079a5..dddce1e6518 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1125,9 +1125,9 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string continue; } - TokenList tokenlist{&mSettings}; - try { + TokenList tokenlist{&mSettings}; + // Create tokens, skip rest of iteration if failed Timer::run("Tokenizer::createTokens", mSettings.showtime, &s_timerResults, [&]() { simplecpp::TokenList tokensP = preprocessor.preprocess(tokens1, mCurrentConfig, files, true); @@ -1136,66 +1136,71 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string hasValidConfig = true; Tokenizer tokenizer(std::move(tokenlist), mSettings, mErrorLogger); - if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) - tokenizer.setTimerResults(&s_timerResults); - tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? - - // locations macros - mLogger->setLocationMacros(tokenizer.tokens(), files); - - // If only errors are printed, print filename after the check - if (!mSettings.quiet && (!mCurrentConfig.empty() || checkCount > 1)) { - std::string fixedpath = Path::toNativeSeparators(file.spath()); - mErrorLogger.reportOut("Checking " + fixedpath + ": " + mCurrentConfig + "...", Color::FgGreen); - } + try { + if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) + tokenizer.setTimerResults(&s_timerResults); + tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? + + // locations macros + mLogger->setLocationMacros(tokenizer.tokens(), files); + + // If only errors are printed, print filename after the check + if (!mSettings.quiet && (!mCurrentConfig.empty() || checkCount > 1)) { + std::string fixedpath = Path::toNativeSeparators(file.spath()); + mErrorLogger.reportOut("Checking " + fixedpath + ": " + mCurrentConfig + "...", Color::FgGreen); + } - if (!tokenizer.tokens()) - continue; + if (!tokenizer.tokens()) + continue; - // skip rest of iteration if just checking configuration - if (mSettings.checkConfiguration) - continue; + // skip rest of iteration if just checking configuration + if (mSettings.checkConfiguration) + continue; #ifdef HAVE_RULES - // Execute rules for "raw" code - executeRules("raw", tokenizer.list); + // Execute rules for "raw" code + executeRules("raw", tokenizer.list); #endif - // Simplify tokens into normal form, skip rest of iteration if failed - if (!tokenizer.simplifyTokens1(mCurrentConfig)) - continue; + // Simplify tokens into normal form, skip rest of iteration if failed + if (!tokenizer.simplifyTokens1(mCurrentConfig)) + continue; - // dump xml if --dump - if ((mSettings.dump || !mSettings.addons.empty()) && fdump.is_open()) { - fdump << "" << std::endl; - fdump << " " << std::endl; - fdump << " " << std::endl; - fdump << " " << std::endl; - fdump << " " << std::endl; - fdump << getLibraryDumpData(); - preprocessor.dump(fdump); - tokenizer.dump(fdump); - fdump << "" << std::endl; - } + // dump xml if --dump + if ((mSettings.dump || !mSettings.addons.empty()) && fdump.is_open()) { + fdump << "" << std::endl; + fdump << " " << std::endl; + fdump << " " << std::endl; + fdump << " " << std::endl; + fdump << " " << std::endl; + fdump << getLibraryDumpData(); + preprocessor.dump(fdump); + tokenizer.dump(fdump); + fdump << "" << std::endl; + } - if (mSettings.inlineSuppressions) { - // Need to call this even if the hash will skip this configuration - mSuppressions.nomsg.markUnmatchedInlineSuppressionsAsChecked(tokenizer); - } + if (mSettings.inlineSuppressions) { + // Need to call this even if the hash will skip this configuration + mSuppressions.nomsg.markUnmatchedInlineSuppressionsAsChecked(tokenizer); + } - // Skip if we already met the same simplified token list - if (mSettings.force || mSettings.maxConfigs > 1) { - const std::size_t hash = tokenizer.list.calculateHash(); - if (hashes.find(hash) != hashes.end()) { - if (mSettings.debugwarnings) - purgedConfigurationMessage(file.spath(), mCurrentConfig); - continue; + // Skip if we already met the same simplified token list + if (mSettings.force || mSettings.maxConfigs > 1) { + const std::size_t hash = tokenizer.list.calculateHash(); + if (hashes.find(hash) != hashes.end()) { + if (mSettings.debugwarnings) + purgedConfigurationMessage(file.spath(), mCurrentConfig); + continue; + } + hashes.insert(hash); } - hashes.insert(hash); - } - // Check normal tokens - checkNormalTokens(tokenizer, analyzerInformation.get()); + // Check normal tokens + checkNormalTokens(tokenizer, analyzerInformation.get()); + } catch (const InternalError &e) { + ErrorMessage errmsg = ErrorMessage::fromInternalError(e, &tokenizer.list, file.spath()); + mErrorLogger.reportErr(errmsg); + } } catch (const simplecpp::Output &o) { // #error etc during preprocessing configurationError.push_back((mCurrentConfig.empty() ? "\'\'" : mCurrentConfig) + " : [" + o.location.file() + ':' + std::to_string(o.location.line) + "] " + o.msg); @@ -1225,7 +1230,7 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string mLogger->setAnalyzerInfo(nullptr); return mLogger->exitcode(); } catch (const InternalError &e) { - ErrorMessage errmsg = ErrorMessage::fromInternalError(e, &tokenlist, file.spath()); + ErrorMessage errmsg = ErrorMessage::fromInternalError(e, nullptr, file.spath()); mErrorLogger.reportErr(errmsg); } }