some `Tokenizer` construction and related other cleanups (#4799)

This commit is contained in:
Oliver Stöneberg 2023-03-02 21:48:14 +01:00 committed by GitHub
parent dac578e8b9
commit 8f5f06add7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 138 additions and 147 deletions

View File

@ -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 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 $(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 $(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 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 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 $(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 $(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 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 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 $(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 $(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 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

View File

@ -147,13 +147,13 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
#else #else
const bool caseSensitive = true; const bool caseSensitive = true;
#endif #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 // filter only for the selected filenames from all project files
std::list<ImportProject::FileSettings> newList; std::list<ImportProject::FileSettings> newList;
const std::list<ImportProject::FileSettings>& fileSettings = settings.project.fileSettings; const std::list<ImportProject::FileSettings>& fileSettings = settings.project.fileSettings;
std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(newList), [&](const ImportProject::FileSettings& fs) { 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()) if (!newList.empty())
settings.project.fileSettings = newList; 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 // Execute recursiveAddFiles() to each given file parameter
const PathMatch matcher(ignored, caseSensitive); const PathMatch matcher(ignored, caseSensitive);
for (const std::string &pathname : pathnames) { 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()) { if (!err.empty()) {
std::cout << "cppcheck: " << err << std::endl; std::cout << "cppcheck: " << err << std::endl;
} }
@ -177,10 +177,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
if (!ignored.empty()) if (!ignored.empty())
std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl; std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl;
return false; return false;
} else if (!mSettings->fileFilters.empty() && settings.project.fileSettings.empty()) { } else if (!settings.fileFilters.empty() && settings.project.fileSettings.empty()) {
std::map<std::string, std::size_t> newMap; std::map<std::string, std::size_t> newMap;
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) for (std::map<std::string, std::size_t>::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; newMap[i->first] = i->second;
} }
mFiles = newMap; mFiles = newMap;
@ -226,11 +226,6 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
return ret; return ret;
} }
void CppCheckExecutor::setSettings(const Settings &settings)
{
mSettings = &settings;
}
int CppCheckExecutor::check_wrapper(CppCheck& cppcheck) int CppCheckExecutor::check_wrapper(CppCheck& cppcheck)
{ {
#ifdef USE_WINDOWS_SEH #ifdef USE_WINDOWS_SEH
@ -266,7 +261,6 @@ bool CppCheckExecutor::reportSuppressions(const Settings &settings, bool unusedF
int CppCheckExecutor::check_internal(CppCheck& cppcheck) int CppCheckExecutor::check_internal(CppCheck& cppcheck)
{ {
Settings& settings = cppcheck.settings(); Settings& settings = cppcheck.settings();
mSettings = &settings;
const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg"); const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg");
for (const std::string &lib : settings.libraries) { for (const std::string &lib : settings.libraries) {
@ -330,8 +324,8 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
unsigned int c = 0; unsigned int c = 0;
if (settings.project.fileSettings.empty()) { if (settings.project.fileSettings.empty()) {
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) {
if (!mSettings->library.markupFile(i->first) if (!settings.library.markupFile(i->first)
|| !mSettings->library.processMarkupAfterCode(i->first)) { || !settings.library.processMarkupAfterCode(i->first)) {
returnValue += cppcheck.check(i->first); returnValue += cppcheck.check(i->first);
processedsize += i->second; processedsize += i->second;
if (!settings.quiet) 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 // second loop to parse all markup files which may not work until all
// c/cpp files have been parsed and checked // c/cpp files have been parsed and checked
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) { for (std::map<std::string, std::size_t>::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); returnValue += cppcheck.check(i->first);
processedsize += i->second; processedsize += i->second;
if (!settings.quiet) if (!settings.quiet)
@ -374,7 +368,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
returnValue = executor.check(); returnValue = executor.check();
} }
cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles); cppcheck.analyseWholeProgram(settings.buildDir, mFiles);
if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) { if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
const bool err = reportSuppressions(settings, cppcheck.isUnusedFunctionCheckEnabled(), mFiles, *this); const bool err = reportSuppressions(settings, cppcheck.isUnusedFunctionCheckEnabled(), mFiles, *this);
@ -413,7 +407,6 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
reportErr(ErrorMessage::getXMLFooter()); reportErr(ErrorMessage::getXMLFooter());
} }
mSettings = nullptr;
if (returnValue) if (returnValue)
return settings.exitCode; return settings.exitCode;
return 0; return 0;

View File

@ -137,12 +137,6 @@ protected:
*/ */
bool parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[]); 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: private:
/** /**
@ -166,7 +160,7 @@ private:
int check_internal(CppCheck& cppcheck); 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; const Settings* mSettings;

View File

@ -800,10 +800,10 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
} }
// Run define rules on raw code // Run define rules on raw code
for (const Settings::Rule &rule : mSettings.rules) { const auto it = std::find_if(mSettings.rules.cbegin(), mSettings.rules.cend(), [](const Settings::Rule& rule) {
if (rule.tokenlist != "define") return rule.tokenlist == "define";
continue; });
if (it != mSettings.rules.cend()) {
std::string code; std::string code;
const std::list<Directive> &directives = preprocessor.getDirectives(); const std::list<Directive> &directives = preprocessor.getDirectives();
for (const Directive &dir : directives) { for (const Directive &dir : directives) {
@ -814,7 +814,6 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
std::istringstream istr2(code); std::istringstream istr2(code);
tokenizer2.list.createTokens(istr2); tokenizer2.list.createTokens(istr2);
executeRules("define", tokenizer2); executeRules("define", tokenizer2);
break;
} }
if (!mSettings.force && configurations.size() > mSettings.maxConfigs) { if (!mSettings.force && configurations.size() > mSettings.maxConfigs) {
@ -871,8 +870,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
continue; continue;
} }
Tokenizer tokenizer(&mSettings, this); Tokenizer tokenizer(&mSettings, this, &preprocessor);
tokenizer.setPreprocessor(&preprocessor);
if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE) if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_NONE)
tokenizer.setTimerResults(&s_timerResults); tokenizer.setTimerResults(&s_timerResults);

View File

@ -588,7 +588,7 @@ namespace {
// TODO : Better evaluation // TODO : Better evaluation
Settings s; Settings s;
std::istringstream istr(c); std::istringstream istr(c);
Tokenizer tokenizer(&s, nullptr); Tokenizer tokenizer(&s);
tokenizer.tokenize(istr,"vcxproj"); tokenizer.tokenize(istr,"vcxproj");
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "(" && tok->astOperand1() && tok->astOperand2()) { if (tok->str() == "(" && tok->astOperand1() && tok->astOperand2()) {

View File

@ -155,35 +155,20 @@ static bool isClassStructUnionEnumStart(const Token * tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
Tokenizer::Tokenizer() : Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger, const Preprocessor *preprocessor) :
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) :
list(settings), list(settings),
mSettings(settings), mSettings(settings),
mErrorLogger(errorLogger), mErrorLogger(errorLogger),
mSymbolDatabase(nullptr), mSymbolDatabase(nullptr),
mTemplateSimplifier(nullptr), mTemplateSimplifier(new TemplateSimplifier(this)),
mVarId(0), mVarId(0),
mUnnamedCount(0), mUnnamedCount(0),
mCodeWithTemplates(false), //is there any templates? mCodeWithTemplates(false), //is there any templates?
mTimerResults(nullptr), mTimerResults(nullptr),
mPreprocessor(nullptr) mPreprocessor(preprocessor)
{ {
// make sure settings are specified // make sure settings are specified
assert(mSettings); assert(mSettings);
mTemplateSimplifier = new TemplateSimplifier(this);
} }
Tokenizer::~Tokenizer() Tokenizer::~Tokenizer()
@ -2773,16 +2758,11 @@ bool Tokenizer::simplifyUsing()
bool Tokenizer::createTokens(std::istream &code, bool Tokenizer::createTokens(std::istream &code,
const std::string& FileName) const std::string& FileName)
{ {
// make sure settings specified
assert(mSettings);
return list.createTokens(code, FileName); return list.createTokens(code, FileName);
} }
void Tokenizer::createTokens(simplecpp::TokenList&& tokenList) void Tokenizer::createTokens(simplecpp::TokenList&& tokenList)
{ {
// make sure settings specified
assert(mSettings);
list.createTokens(std::move(tokenList)); list.createTokens(std::move(tokenList));
} }
@ -9811,8 +9791,8 @@ void Tokenizer::simplifyNamespaceAliases()
bool Tokenizer::hasIfdef(const Token *start, const Token *end) const bool Tokenizer::hasIfdef(const Token *start, const Token *end) const
{ {
if (!mPreprocessor) assert(mPreprocessor);
return false;
return std::any_of(mPreprocessor->getDirectives().cbegin(), mPreprocessor->getDirectives().cend(), [&](const Directive& d) { return std::any_of(mPreprocessor->getDirectives().cbegin(), mPreprocessor->getDirectives().cend(), [&](const Directive& d) {
return d.str.compare(0, 3, "#if") == 0 && return d.str.compare(0, 3, "#if") == 0 &&
d.linenr >= start->linenr() && d.linenr >= start->linenr() &&

View File

@ -25,6 +25,7 @@
#include "errortypes.h" #include "errortypes.h"
#include "tokenlist.h" #include "tokenlist.h"
#include <cassert>
#include <iosfwd> #include <iosfwd>
#include <list> #include <list>
#include <map> #include <map>
@ -59,8 +60,7 @@ class CPPCHECKLIB Tokenizer {
friend class TemplateSimplifier; friend class TemplateSimplifier;
public: public:
Tokenizer(); explicit Tokenizer(const Settings * settings, ErrorLogger *errorLogger = nullptr, const Preprocessor *preprocessor = nullptr);
Tokenizer(const Settings * settings, ErrorLogger *errorLogger);
~Tokenizer(); ~Tokenizer();
void setTimerResults(TimerResults *tr) { void setTimerResults(TimerResults *tr) {
@ -377,10 +377,8 @@ public:
*/ */
static const Token * isFunctionHead(const Token *tok, const std::string &endsWith, bool cpp); static const Token * isFunctionHead(const Token *tok, const std::string &endsWith, bool cpp);
void setPreprocessor(const Preprocessor *preprocessor) {
mPreprocessor = preprocessor;
}
const Preprocessor *getPreprocessor() const { const Preprocessor *getPreprocessor() const {
assert(mPreprocessor);
return mPreprocessor; return mPreprocessor;
} }
@ -621,12 +619,6 @@ public:
return mCodeWithTemplates; return mCodeWithTemplates;
} }
void setSettings(const Settings *settings) {
mSettings = settings;
list.setSettings(settings);
}
const SymbolDatabase *getSymbolDatabase() const { const SymbolDatabase *getSymbolDatabase() const {
return mSymbolDatabase; return mSymbolDatabase;
} }
@ -703,7 +695,7 @@ private:
void setPodTypes(); void setPodTypes();
/** settings */ /** settings */
const Settings * mSettings; const Settings * const mSettings;
/** errorlogger */ /** errorlogger */
ErrorLogger* const mErrorLogger; ErrorLogger* const mErrorLogger;
@ -711,7 +703,7 @@ private:
/** Symbol database that all checks etc can use */ /** Symbol database that all checks etc can use */
SymbolDatabase *mSymbolDatabase; SymbolDatabase *mSymbolDatabase;
TemplateSimplifier *mTemplateSimplifier; TemplateSimplifier * const mTemplateSimplifier;
/** E.g. "A" for code where "#ifdef A" is true. This is used to /** E.g. "A" for code where "#ifdef A" is true. This is used to
print additional information in error situations. */ print additional information in error situations. */
@ -746,7 +738,7 @@ private:
*/ */
TimerResults *mTimerResults; TimerResults *mTimerResults;
const Preprocessor *mPreprocessor; const Preprocessor * const mPreprocessor;
}; };
/// @} /// @}

View File

@ -23,7 +23,6 @@
#include "errortypes.h" #include "errortypes.h"
#include "standards.h" #include "standards.h"
#include "library.h" #include "library.h"
#include "preprocessor.h"
#include "settings.h" #include "settings.h"
#include "fixture.h" #include "fixture.h"
#include "tokenize.h" #include "tokenize.h"
@ -99,14 +98,10 @@ private:
std::map<std::string, simplecpp::TokenList*> filedata; std::map<std::string, simplecpp::TokenList*> filedata;
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
Preprocessor preprocessor(*settings, nullptr);
preprocessor.setDirectives(tokens1);
// Tokenizer.. // Tokenizer..
Tokenizer tokenizer(settings, this); Tokenizer tokenizer(settings, this);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
tokenizer.setPreprocessor(&preprocessor);
// Check for buffer overruns.. // Check for buffer overruns..
runChecks<CheckBufferOverrun>(&tokenizer, settings, this); runChecks<CheckBufferOverrun>(&tokenizer, settings, this);

View File

@ -20,6 +20,7 @@
#include "checkclass.h" #include "checkclass.h"
#include "errortypes.h" #include "errortypes.h"
#include "library.h" #include "library.h"
#include "preprocessor.h"
#include "settings.h" #include "settings.h"
#include "fixture.h" #include "fixture.h"
#include "tokenize.h" #include "tokenize.h"
@ -260,8 +261,10 @@ private:
Settings settings; Settings settings;
settings.severity.enable(Severity::warning); settings.severity.enable(Severity::warning);
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -364,8 +367,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -516,8 +521,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings1, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -677,8 +684,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -1124,8 +1133,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -1598,8 +1609,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings1, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -2560,8 +2573,10 @@ private:
settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings0.severity.enable(Severity::warning); settings0.severity.enable(Severity::warning);
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -2877,12 +2892,14 @@ private:
checkNoMemset_(file, line, code, settings); 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 // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -3512,8 +3529,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings1, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -3550,8 +3569,10 @@ private:
s = &settings0; s = &settings0;
s->certainty.setEnabled(Certainty::inconclusive, inconclusive); s->certainty.setEnabled(Certainty::inconclusive, inconclusive);
Preprocessor preprocessor(*s, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(s, this); Tokenizer tokenizer(s, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7060,8 +7081,10 @@ private:
// Check.. // Check..
settings0.certainty.setEnabled(Certainty::inconclusive, true); settings0.certainty.setEnabled(Certainty::inconclusive, true);
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7096,8 +7119,10 @@ private:
Settings settings; Settings settings;
settings.severity.enable(Severity::performance); settings.severity.enable(Severity::performance);
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7308,8 +7333,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings0, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7415,24 +7442,23 @@ private:
#define checkVirtualFunctionCall(...) checkVirtualFunctionCall_(__FILE__, __LINE__, __VA_ARGS__) #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 // Clear the error log
errout.str(""); errout.str("");
// Check.. // Check..
if (!s) { Settings settings;
static Settings settings_; settings.severity.enable(Severity::warning);
s = &settings_; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
s->severity.enable(Severity::warning);
} Preprocessor preprocessor(settings, nullptr);
s->certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(s, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
CheckClass checkClass(&tokenizer, s, this); CheckClass checkClass(&tokenizer, &settings, this);
checkClass.checkVirtualFunctionCallInConstructor(); checkClass.checkVirtualFunctionCallInConstructor();
} }
@ -7774,8 +7800,10 @@ private:
Settings settings; Settings settings;
settings.severity.enable(Severity::style); settings.severity.enable(Severity::style);
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7950,8 +7978,10 @@ private:
settings.safeChecks.classes = true; settings.safeChecks.classes = true;
settings.severity.enable(Severity::warning); settings.severity.enable(Severity::warning);
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -7971,8 +8001,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings1, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
@ -8168,8 +8200,10 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Preprocessor preprocessor(settings1, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);

View File

@ -160,10 +160,9 @@ private:
preprocessor.setDirectives(tokens1); preprocessor.setDirectives(tokens1);
// Tokenizer.. // Tokenizer..
Tokenizer tokenizer(settings, this); Tokenizer tokenizer(settings, this, &preprocessor);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
tokenizer.setPreprocessor(&preprocessor);
// Run checks.. // Run checks..
runChecks<CheckCondition>(&tokenizer, settings, this); runChecks<CheckCondition>(&tokenizer, settings, this);

View File

@ -19,6 +19,7 @@
#include "check.h" #include "check.h"
#include "errortypes.h" #include "errortypes.h"
#include "mathlib.h" #include "mathlib.h"
#include "preprocessor.h"
#include "settings.h" #include "settings.h"
#include "fixture.h" #include "fixture.h"
#include "token.h" #include "token.h"
@ -286,8 +287,10 @@ private:
std::string checkCodeInternal_(const std::string &code, const char* filename, const char* file, int line) { std::string checkCodeInternal_(const std::string &code, const char* filename, const char* file, int line) {
errout.str(""); errout.str("");
Preprocessor preprocessor(settings, nullptr);
// tokenize.. // tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line);

View File

@ -306,8 +306,10 @@ private:
settings->certainty.setEnabled(Certainty::experimental, experimental); settings->certainty.setEnabled(Certainty::experimental, experimental);
settings->verbose = verbose; settings->verbose = verbose;
Preprocessor preprocessor(*settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(settings, this); Tokenizer tokenizer(settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, filename ? filename : "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, filename ? filename : "test.cpp"), file, line);
@ -349,17 +351,16 @@ private:
preprocessor.setDirectives(tokens1); preprocessor.setDirectives(tokens1);
// Tokenizer.. // Tokenizer..
Tokenizer tokenizer(settings, this); Tokenizer tokenizer(settings, this, &preprocessor);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
tokenizer.setPreprocessor(&preprocessor);
// Check.. // Check..
runChecks<CheckOther>(&tokenizer, settings, this); runChecks<CheckOther>(&tokenizer, settings, this);
} }
void checkInterlockedDecrement(const char code[]) { void checkInterlockedDecrement(const char code[]) {
static Settings settings; Settings settings;
settings.platformType = Settings::Win32A; settings.platformType = Settings::Win32A;
check(code, nullptr, false, false, true, false, &settings); check(code, nullptr, false, false, true, false, &settings);
@ -1543,12 +1544,14 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
static Settings settings; Settings settings;
settings.severity.enable(Severity::style); settings.severity.enable(Severity::style);
settings.standards.cpp = Standards::CPP03; // #5560 settings.standards.cpp = Standards::CPP03; // #5560
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizerCpp(&settings, this); Tokenizer tokenizerCpp(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizerCpp.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizerCpp.tokenize(istr, "test.cpp"), file, line);
@ -1749,10 +1752,12 @@ private:
if (portability) if (portability)
settings.severity.enable(Severity::portability); settings.severity.enable(Severity::portability);
settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings.defaultSign = 's'; settings.defaultSign = 's';
Preprocessor preprocessor(settings, nullptr);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);

View File

@ -64,7 +64,7 @@ public:
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI(), &outputList); simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI(), &outputList);
if (errorLogger) { if (errorLogger) {
static Settings settings; Settings settings;
Preprocessor p(settings, errorLogger); Preprocessor p(settings, errorLogger);
p.reportOutput(outputList, true); p.reportOutput(outputList, true);
} }

View File

@ -44,14 +44,10 @@ private:
} }
#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) #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.. // Clear the error buffer..
errout.str(""); errout.str("");
if (!settings) {
static Settings _settings;
settings = &_settings;
}
settings->severity.enable(Severity::warning); settings->severity.enable(Severity::warning);
settings->severity.enable(Severity::portability); settings->severity.enable(Severity::portability);
settings->standards.setCPP(standard); settings->standards.setCPP(standard);
@ -66,6 +62,7 @@ private:
} }
void checkTooBigShift_Unix32() { void checkTooBigShift_Unix32() {
Settings settings0;
Settings settings; Settings settings;
PLATFORM(settings, Settings::Unix32); PLATFORM(settings, Settings::Unix32);
@ -166,7 +163,7 @@ private:
// #7266: C++, shift in macro // #7266: C++, shift in macro
check("void f(unsigned int x) {\n" check("void f(unsigned int x) {\n"
" UINFO(x << 1234);\n" " UINFO(x << 1234);\n"
"}"); "}", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #8640 // #8640
@ -176,7 +173,7 @@ private:
" constexpr const int shift[1] = {32};\n" " constexpr const int shift[1] = {32};\n"
" constexpr const int ret = a << shift[0];\n" // shift too many bits " constexpr const int ret = a << shift[0];\n" // shift too many bits
" return ret;\n" " return ret;\n"
"}"); "}", &settings0);
ASSERT_EQUALS("[test.cpp:5]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n" 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<<shift[0]'.\n", errout.str()); "[test.cpp:5]: (error) Signed integer overflow for expression 'a<<shift[0]'.\n", errout.str());
@ -187,7 +184,7 @@ private:
" if (k > 32)\n" " if (k > 32)\n"
" return 0;\n" " return 0;\n"
" return rm>> k;\n" " return rm>> k;\n"
"}"); "}", &settings0);
ASSERT_EQUALS( 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", "[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()); errout.str());
@ -199,7 +196,7 @@ private:
" return 0;\n" " return 0;\n"
" else\n" " else\n"
" return rm>> k;\n" " return rm>> k;\n"
"}"); "}", &settings0);
ASSERT_EQUALS( 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", "[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()); errout.str());
@ -211,20 +208,20 @@ private:
" return 0;\n" " return 0;\n"
" else\n" " else\n"
" return rm>> k;\n" " return rm>> k;\n"
"}"); "}", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("static long long f(int x, long long y) {\n" check("static long long f(int x, long long y) {\n"
" if (x >= 64)\n" " if (x >= 64)\n"
" return 0;\n" " return 0;\n"
" return -(y << (x-1));\n" " return -(y << (x-1));\n"
"}"); "}", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("bool f() {\n" check("bool f() {\n"
" std::ofstream outfile;\n" " std::ofstream outfile;\n"
" outfile << vec_points[0](0) << static_cast<int>(d) << ' ';\n" " outfile << vec_points[0](0) << static_cast<int>(d) << ' ';\n"
"}"); "}", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(unsigned b, int len, unsigned char rem) {\n" // #10773 check("void f(unsigned b, int len, unsigned char rem) {\n" // #10773
@ -235,7 +232,7 @@ private:
" if (bits == 512)\n" " if (bits == 512)\n"
" len -= 8;\n" " len -= 8;\n"
" }\n" " }\n"
"}\n"); "}\n", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -282,12 +279,13 @@ private:
} }
void signConversion() { void signConversion() {
Settings settings0;
Settings settings; Settings settings;
PLATFORM(settings, Settings::Unix64); 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()); 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()); 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 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 check("unsigned int f1(signed int x, unsigned int y) {" // x is signed
" return x * y;\n" " return x * y;\n"
"}\n" "}\n"
"void f2() { f1(-4,4); }"); "void f2() { f1(-4,4); }", &settings0);
ASSERT_EQUALS( 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", "[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()); errout.str());
@ -307,7 +305,7 @@ private:
check("unsigned int f1(int x) {" check("unsigned int f1(int x) {"
" return x * 5U;\n" " return x * 5U;\n"
"}\n" "}\n"
"void f2() { f1(-4); }"); "void f2() { f1(-4); }", &settings0);
ASSERT_EQUALS( 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", "[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()); errout.str());
@ -315,19 +313,19 @@ private:
check("unsigned int f1(int x) {" // #6168: FP for inner calculation check("unsigned int f1(int x) {" // #6168: FP for inner calculation
" return 5U * (1234 - x);\n" // <- signed subtraction, x is not sign converted " return 5U * (1234 - x);\n" // <- signed subtraction, x is not sign converted
"}\n" "}\n"
"void f2() { f1(-4); }"); "void f2() { f1(-4); }", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// Don't warn for + and - // Don't warn for + and -
check("void f1(int x) {" check("void f1(int x) {"
" a = x + 5U;\n" " a = x + 5U;\n"
"}\n" "}\n"
"void f2() { f1(-4); }"); "void f2() { f1(-4); }", &settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("size_t foo(size_t x) {\n" check("size_t foo(size_t x) {\n"
" return -2 * 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()); 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() { 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())); ASSERT_EQUALS("[test.cpp:1]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" return (int)1E100;\n" " return (int)1E100;\n"
"}"); "}", &settings);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" return (int)-1E100;\n" " return (int)-1E100;\n"
"}"); "}", &settings);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" return (short)1E6;\n" " return (short)1E6;\n"
"}"); "}", &settings);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" return (unsigned char)256.0;\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())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" return (unsigned char)255.5;\n" " return (unsigned char)255.5;\n"
"}"); "}", &settings);
ASSERT_EQUALS("", removeFloat(errout.str())); ASSERT_EQUALS("", removeFloat(errout.str()));
check("void f(void) {\n" check("void f(void) {\n"
" char c = 1234.5;\n" " char c = 1234.5;\n"
"}"); "}", &settings);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
check("char f(void) {\n" check("char f(void) {\n"
" return 1234.5;\n" " return 1234.5;\n"
"}"); "}", &settings);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str())); ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout.str()));
} }
}; };

View File

@ -256,8 +256,7 @@ private:
preprocessor.setDirectives(*directives); preprocessor.setDirectives(*directives);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this, &preprocessor);
tokenizer.setPreprocessor(&preprocessor);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);