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

View File

@ -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<ImportProject::FileSettings> newList;
const std::list<ImportProject::FileSettings>& 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<std::string, std::size_t> newMap;
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;
}
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<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);
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<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);
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;

View File

@ -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;

View File

@ -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<Directive> &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);

View File

@ -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()) {

View File

@ -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() &&

View File

@ -25,6 +25,7 @@
#include "errortypes.h"
#include "tokenlist.h"
#include <cassert>
#include <iosfwd>
#include <list>
#include <map>
@ -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;
};
/// @}

View File

@ -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<std::string, simplecpp::TokenList*> 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<CheckBufferOverrun>(&tokenizer, settings, this);

View File

@ -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);

View File

@ -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<CheckCondition>(&tokenizer, settings, this);

View File

@ -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);

View File

@ -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<CheckOther>(&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);

View File

@ -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);
}

View File

@ -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<<shift[0]'.\n", errout.str());
@ -187,7 +184,7 @@ private:
" if (k > 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<int>(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()));
}
};

View File

@ -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);