From 9117ca42a8a7125d5897b9b077d6f2c9c189495d Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 28 Feb 2024 16:15:30 +0100 Subject: [PATCH 1/3] moved preprocessor usage into `Tokenizer` --- Makefile | 2 +- lib/checkunusedvar.cpp | 11 ++--------- lib/tokenize.cpp | 10 ++++++++++ lib/tokenize.h | 8 ++------ 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 22f1823feea..41177cbc9bd 100644 --- a/Makefile +++ b/Makefile @@ -553,7 +553,7 @@ $(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astuti $(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp $(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index dc8a901f7ba..d19e32c70c0 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -24,7 +24,6 @@ #include "errortypes.h" #include "fwdanalysis.h" #include "library.h" -#include "preprocessor.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -1460,14 +1459,8 @@ void CheckUnusedVar::checkStructMemberUsage() // Packed struct => possibly used by lowlevel code. Struct members might be required by hardware. if (scope.bodyEnd->isAttributePacked()) continue; - if (const Preprocessor *preprocessor = mTokenizer->getPreprocessor()) { - const auto& directives = preprocessor->getDirectives(); - const bool isPacked = std::any_of(directives.cbegin(), directives.cend(), [&](const Directive& d) { - return d.linenr < scope.bodyStart->linenr() && d.str == "#pragma pack(1)" && d.file == mTokenizer->list.getFiles().front(); - }); - if (isPacked) - continue; - } + if (mTokenizer->isPacked(scope.bodyStart)) + continue; // Bail out for template struct, members might be used in non-matching instantiations if (scope.className.find('<') != std::string::npos) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6bc6d56a929..d18dc00d8cd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10589,3 +10589,13 @@ bool Tokenizer::hasIfdef(const Token *start, const Token *end) const d.file == list.getFiles()[start->fileIndex()]; }); } + +bool Tokenizer::isPacked(const Token * bodyStart) const +{ + assert(mPreprocessor); + + const auto& directives = mPreprocessor->getDirectives(); + return std::any_of(directives.cbegin(), directives.cend(), [&](const Directive& d) { + return d.linenr < bodyStart->linenr() && d.str == "#pragma pack(1)" && d.file == list.getFiles().front(); + }); +} diff --git a/lib/tokenize.h b/lib/tokenize.h index 20355a06d39..dcc5ecf5a4e 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -24,7 +24,6 @@ #include "config.h" #include "tokenlist.h" -#include #include #include #include @@ -367,13 +366,10 @@ class CPPCHECKLIB Tokenizer { */ static const Token * isFunctionHead(const Token *tok, const std::string &endsWith); - const Preprocessor *getPreprocessor() const { - assert(mPreprocessor); - return mPreprocessor; - } - bool hasIfdef(const Token *start, const Token *end) const; + bool isPacked(const Token * bodyStart) const; + private: /** Simplify pointer to standard type (C only) */ From 3b83cab71380f154160e8707e0cbd33cd6c1dcd5 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 28 Feb 2024 16:27:35 +0100 Subject: [PATCH 2/3] Preprocessor: made test-only `setDirectives()` overload private --- lib/preprocessor.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 0053807cd51..a902e1e953e 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -73,6 +73,7 @@ class CPPCHECKLIB Preprocessor { // TODO: get rid of this friend class PreprocessorHelper; friend class TestPreprocessor; + friend class TestUnusedVar; public: @@ -93,9 +94,6 @@ class CPPCHECKLIB Preprocessor { void inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions); void setDirectives(const simplecpp::TokenList &tokens); - void setDirectives(const std::list &directives) { - mDirectives = directives; - } /** list of all directives met while preprocessing file */ const std::list &getDirectives() const { @@ -183,6 +181,10 @@ class CPPCHECKLIB Preprocessor { static bool hasErrors(const simplecpp::OutputList &outputList); + void setDirectives(const std::list &directives) { + mDirectives = directives; + } + const Settings& mSettings; ErrorLogger *mErrorLogger; From 14085aeeaff3445e9e34c2594efd19fb7f5441c0 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 28 Feb 2024 16:21:25 +0100 Subject: [PATCH 3/3] Tokenizer: added `isPacked()` TODO --- lib/tokenize.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d18dc00d8cd..fbaa0571a6a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10595,6 +10595,7 @@ bool Tokenizer::isPacked(const Token * bodyStart) const assert(mPreprocessor); const auto& directives = mPreprocessor->getDirectives(); + // TODO: should this return true if the #pragma exists in any line before the start token? return std::any_of(directives.cbegin(), directives.cend(), [&](const Directive& d) { return d.linenr < bodyStart->linenr() && d.str == "#pragma pack(1)" && d.file == list.getFiles().front(); });