refs #12171 - start generating unmatched suppressions with `FileSettings` / improved TestSuppressions / some cleanups (#5827)

This commit is contained in:
Oliver Stöneberg 2024-01-04 21:32:21 +01:00 committed by GitHub
parent 615e4c01c4
commit b2e0b3b425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 250 additions and 85 deletions

View File

@ -42,6 +42,7 @@
#endif #endif
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstdio> #include <cstdio>
#include <cstdlib> // EXIT_SUCCESS and EXIT_FAILURE #include <cstdlib> // EXIT_SUCCESS and EXIT_FAILURE
#include <ctime> #include <ctime>
@ -217,21 +218,29 @@ int CppCheckExecutor::check_wrapper(CppCheck& cppcheck)
return check_internal(cppcheck); return check_internal(cppcheck);
} }
bool CppCheckExecutor::reportSuppressions(const Settings &settings, bool unusedFunctionCheckEnabled, const std::list<std::pair<std::string, std::size_t>> &files, ErrorLogger& errorLogger) { bool CppCheckExecutor::reportSuppressions(const Settings &settings, const Suppressions& suppressions, bool unusedFunctionCheckEnabled, const std::list<std::pair<std::string, std::size_t>> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
const auto& suppressions = settings.nomsg.getSuppressions(); const auto& suppr = suppressions.getSuppressions();
if (std::any_of(suppressions.begin(), suppressions.end(), [](const Suppressions::Suppression& s) { if (std::any_of(suppr.begin(), suppr.end(), [](const Suppressions::Suppression& s) {
return s.errorId == "unmatchedSuppression" && s.fileName.empty() && s.lineNumber == Suppressions::Suppression::NO_LINE; return s.errorId == "unmatchedSuppression" && s.fileName.empty() && s.lineNumber == Suppressions::Suppression::NO_LINE;
})) }))
return false; return false;
bool err = false; bool err = false;
if (settings.useSingleJob()) { if (settings.useSingleJob()) {
// the two inputs may only be used exclusively
assert(!(!files.empty() && !fileSettings.empty()));
for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = files.cbegin(); i != files.cend(); ++i) { for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = files.cbegin(); i != files.cend(); ++i) {
err |= Suppressions::reportUnmatchedSuppressions( err |= Suppressions::reportUnmatchedSuppressions(
settings.nomsg.getUnmatchedLocalSuppressions(i->first, unusedFunctionCheckEnabled), errorLogger); suppressions.getUnmatchedLocalSuppressions(i->first, unusedFunctionCheckEnabled), errorLogger);
}
for (std::list<FileSettings>::const_iterator i = fileSettings.cbegin(); i != fileSettings.cend(); ++i) {
err |= Suppressions::reportUnmatchedSuppressions(
suppressions.getUnmatchedLocalSuppressions(i->filename, unusedFunctionCheckEnabled), errorLogger);
} }
} }
err |= Suppressions::reportUnmatchedSuppressions(settings.nomsg.getUnmatchedGlobalSuppressions(unusedFunctionCheckEnabled), errorLogger); err |= Suppressions::reportUnmatchedSuppressions(suppressions.getUnmatchedGlobalSuppressions(unusedFunctionCheckEnabled), errorLogger);
return err; return err;
} }
@ -277,7 +286,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings); cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings);
if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) { if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
const bool err = reportSuppressions(settings, cppcheck.isUnusedFunctionCheckEnabled(), mFiles, *mStdLogger); const bool err = reportSuppressions(settings, settings.nomsg, cppcheck.isUnusedFunctionCheckEnabled(), mFiles, mFileSettings, *mStdLogger);
if (err && returnValue == 0) if (err && returnValue == 0)
returnValue = settings.exitCode; returnValue = settings.exitCode;
} }

View File

@ -31,6 +31,7 @@
class CppCheck; class CppCheck;
class Settings; class Settings;
class ErrorLogger; class ErrorLogger;
class Suppressions;
/** /**
* This class works as an example of how CppCheck can be used in external * This class works as an example of how CppCheck can be used in external
@ -81,7 +82,7 @@ private:
protected: protected:
static bool reportSuppressions(const Settings &settings, bool unusedFunctionCheckEnabled, const std::list<std::pair<std::string, std::size_t>> &files, ErrorLogger& errorLogger); static bool reportSuppressions(const Settings &settings, const Suppressions& suppressions, bool unusedFunctionCheckEnabled, const std::list<std::pair<std::string, std::size_t>> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger);
/** /**
* Wrapper around check_internal * Wrapper around check_internal

View File

@ -53,18 +53,23 @@ private:
TEST_CASE(suppressionsGlob); TEST_CASE(suppressionsGlob);
TEST_CASE(suppressionsGlobId); TEST_CASE(suppressionsGlobId);
TEST_CASE(suppressionsFileNameWithExtraPath); TEST_CASE(suppressionsFileNameWithExtraPath);
TEST_CASE(suppressionsSettings); TEST_CASE(suppressionsSettingsFiles);
TEST_CASE(suppressionsSettingsThreads); TEST_CASE(suppressionsSettingsFS);
TEST_CASE(suppressionsSettingsThreadsFiles);
TEST_CASE(suppressionsSettingsThreadsFS);
#if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) #if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
TEST_CASE(suppressionsSettingsProcesses); TEST_CASE(suppressionsSettingsProcessesFiles);
TEST_CASE(suppressionsSettingsProcessesFS);
#endif #endif
TEST_CASE(suppressionsMultiFile); TEST_CASE(suppressionsMultiFileFiles);
TEST_CASE(suppressionsMultiFileFS);
TEST_CASE(suppressionsPathSeparator); TEST_CASE(suppressionsPathSeparator);
TEST_CASE(suppressionsLine0); TEST_CASE(suppressionsLine0);
TEST_CASE(suppressionsFileComment); TEST_CASE(suppressionsFileComment);
TEST_CASE(inlinesuppress); TEST_CASE(inlinesuppress);
TEST_CASE(inlinesuppress_symbolname); TEST_CASE(inlinesuppress_symbolname_Files);
TEST_CASE(inlinesuppress_symbolname_FS);
TEST_CASE(inlinesuppress_comment); TEST_CASE(inlinesuppress_comment);
TEST_CASE(multi_inlinesuppress); TEST_CASE(multi_inlinesuppress);
@ -75,14 +80,21 @@ private:
TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction
TEST_CASE(globalsuppress_unusedFunction); // #4946 TEST_CASE(globalsuppress_unusedFunction); // #4946
TEST_CASE(suppressionWithRelativePaths); // #4733 TEST_CASE(suppressionWithRelativePaths); // #4733
TEST_CASE(suppressingSyntaxErrors); // #7076 TEST_CASE(suppressingSyntaxErrorsFiles); // #7076
TEST_CASE(suppressingSyntaxErrorsInline); // #5917 TEST_CASE(suppressingSyntaxErrorsFS); // #7076
TEST_CASE(suppressingSyntaxErrorsWhileFileRead); // PR #1333 TEST_CASE(suppressingSyntaxErrorsInlineFiles); // #5917
TEST_CASE(suppressingSyntaxErrorsInlineFS); // #5917
TEST_CASE(suppressingSyntaxErrorsWhileFileReadFiles); // PR #1333
TEST_CASE(suppressingSyntaxErrorsWhileFileReadFS); // PR #1333
TEST_CASE(symbol); TEST_CASE(symbol);
TEST_CASE(unusedFunction); TEST_CASE(unusedFunctionFiles);
TEST_CASE(unusedFunctionFS);
TEST_CASE(suppressingSyntaxErrorAndExitCode); TEST_CASE(suppressingSyntaxErrorAndExitCodeFiles);
TEST_CASE(suppressingSyntaxErrorAndExitCodeFS);
TEST_CASE(suppressingSyntaxErrorAndExitCodeMultiFileFiles);
TEST_CASE(suppressingSyntaxErrorAndExitCodeMultiFileFS);
TEST_CASE(suppressLocal); TEST_CASE(suppressLocal);
TEST_CASE(suppressUnmatchedSuppressions); TEST_CASE(suppressUnmatchedSuppressions);
@ -188,22 +200,45 @@ private:
ASSERT_EQUALS(true, suppressions.isSuppressed(errorMessage("errorid", "x/../a.c", 123))); ASSERT_EQUALS(true, suppressions.isSuppressed(errorMessage("errorid", "x/../a.c", 123)));
} }
unsigned int checkSuppressionFiles(const char code[], const std::string &suppression = emptyString) {
return _checkSuppression(code, false, suppression);
}
unsigned int checkSuppressionFS(const char code[], const std::string &suppression = emptyString) {
return _checkSuppression(code, true, suppression);
}
// Check the suppression // Check the suppression
unsigned int checkSuppression(const char code[], const std::string &suppression = emptyString) { unsigned int _checkSuppression(const char code[], bool useFS, const std::string &suppression = emptyString) {
std::map<std::string, std::string> files; std::map<std::string, std::string> files;
files["test.cpp"] = code; files["test.cpp"] = code;
return checkSuppression(files, suppression); return _checkSuppression(files, useFS, suppression);
}
unsigned int checkSuppressionFiles(std::map<std::string, std::string> &f, const std::string &suppression = emptyString) {
return _checkSuppression(f, false, suppression);
}
unsigned int checkSuppressionFS(std::map<std::string, std::string> &f, const std::string &suppression = emptyString) {
return _checkSuppression(f, true, suppression);
} }
// Check the suppression for multiple files // Check the suppression for multiple files
unsigned int checkSuppression(std::map<std::string, std::string> &f, const std::string &suppression = emptyString) { unsigned int _checkSuppression(std::map<std::string, std::string> &f, bool useFS, const std::string &suppression = emptyString) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
std::list<std::pair<std::string, std::size_t>> files; std::list<FileSettings> fileSettings;
std::list<std::pair<std::string, std::size_t>> filelist;
for (std::map<std::string, std::string>::const_iterator i = f.cbegin(); i != f.cend(); ++i) { for (std::map<std::string, std::string>::const_iterator i = f.cbegin(); i != f.cend(); ++i) {
files.emplace_back(i->first, i->second.size()); filelist.emplace_back(i->first, i->second.size());
if (useFS) {
FileSettings fs;
fs.filename = i->first;
fileSettings.emplace_back(std::move(fs));
}
} }
CppCheck cppCheck(*this, true, nullptr); CppCheck cppCheck(*this, true, nullptr);
@ -217,26 +252,44 @@ private:
if (!suppression.empty()) { if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression)); EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
} }
// TODO: test with FS
std::list<FileSettings> fileSettings;
SingleExecutor executor(cppCheck, files, fileSettings, settings, settings.nomsg, *this);
std::vector<std::unique_ptr<ScopedFile>> scopedfiles; std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
scopedfiles.reserve(files.size()); scopedfiles.reserve(filelist.size());
for (std::map<std::string, std::string>::const_iterator i = f.cbegin(); i != f.cend(); ++i) for (std::map<std::string, std::string>::const_iterator i = f.cbegin(); i != f.cend(); ++i)
scopedfiles.emplace_back(new ScopedFile(i->first, i->second)); scopedfiles.emplace_back(new ScopedFile(i->first, i->second));
// clear files list so only fileSettings are used
if (useFS)
filelist.clear();
SingleExecutor executor(cppCheck, filelist, fileSettings, settings, settings.nomsg, *this);
const unsigned int exitCode = executor.check(); const unsigned int exitCode = executor.check();
CppCheckExecutor::reportSuppressions(settings, false, files, *this); CppCheckExecutor::reportSuppressions(settings, settings.nomsg, false, filelist, fileSettings, *this);
return exitCode; return exitCode;
} }
unsigned int checkSuppressionThreads(const char code[], const std::string &suppression = emptyString) { unsigned int checkSuppressionThreadsFiles(const char code[], const std::string &suppression = emptyString) {
return _checkSuppressionThreads(code, false, suppression);
}
unsigned int checkSuppressionThreadsFS(const char code[], const std::string &suppression = emptyString) {
return _checkSuppressionThreads(code, true, suppression);
}
unsigned int _checkSuppressionThreads(const char code[], bool useFS, const std::string &suppression = emptyString) {
errout.str(""); errout.str("");
std::list<std::pair<std::string, std::size_t>> files; std::list<FileSettings> fileSettings;
files.emplace_back("test.cpp", strlen(code));
std::list<std::pair<std::string, std::size_t>> filelist;
filelist.emplace_back("test.cpp", strlen(code));
if (useFS) {
FileSettings fs;
fs.filename = "test.cpp";
fileSettings.emplace_back(std::move(fs));
}
Settings settings; Settings settings;
settings.jobs = 2; settings.jobs = 2;
@ -246,27 +299,45 @@ private:
if (!suppression.empty()) { if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression)); EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
} }
// TODO: test with FS
std::list<FileSettings> fileSettings;
ThreadExecutor executor(files, fileSettings, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
std::vector<std::unique_ptr<ScopedFile>> scopedfiles; std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
scopedfiles.reserve(files.size()); scopedfiles.reserve(filelist.size());
for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = files.cbegin(); i != files.cend(); ++i) for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i)
scopedfiles.emplace_back(new ScopedFile(i->first, code)); scopedfiles.emplace_back(new ScopedFile(i->first, code));
// clear files list so only fileSettings are used
if (useFS)
filelist.clear();
ThreadExecutor executor(filelist, fileSettings, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
const unsigned int exitCode = executor.check(); const unsigned int exitCode = executor.check();
CppCheckExecutor::reportSuppressions(settings, false, files, *this); CppCheckExecutor::reportSuppressions(settings, settings.nomsg, false, filelist, fileSettings, *this);
return exitCode; return exitCode;
} }
#if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) #if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
unsigned int checkSuppressionProcesses(const char code[], const std::string &suppression = emptyString) { unsigned int checkSuppressionProcessesFiles(const char code[], const std::string &suppression = emptyString) {
return _checkSuppressionProcesses(code, false, suppression);
}
unsigned int checkSuppressionProcessesFS(const char code[], const std::string &suppression = emptyString) {
return _checkSuppressionProcesses(code, true, suppression);
}
unsigned int _checkSuppressionProcesses(const char code[], bool useFS, const std::string &suppression = emptyString) {
errout.str(""); errout.str("");
std::list<std::pair<std::string, std::size_t>> files; std::list<FileSettings> fileSettings;
files.emplace_back("test.cpp", strlen(code));
std::list<std::pair<std::string, std::size_t>> filelist;
filelist.emplace_back("test.cpp", strlen(code));
if (useFS) {
FileSettings fs;
fs.filename = "test.cpp";
fileSettings.emplace_back(std::move(fs));
}
Settings settings; Settings settings;
settings.jobs = 2; settings.jobs = 2;
@ -276,17 +347,20 @@ private:
if (!suppression.empty()) { if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression)); EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
} }
// TODO: test with FS
std::list<FileSettings> fileSettings;
ProcessExecutor executor(files, fileSettings, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
std::vector<std::unique_ptr<ScopedFile>> scopedfiles; std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
scopedfiles.reserve(files.size()); scopedfiles.reserve(filelist.size());
for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = files.cbegin(); i != files.cend(); ++i) for (std::list<std::pair<std::string, std::size_t>>::const_iterator i = filelist.cbegin(); i != filelist.cend(); ++i)
scopedfiles.emplace_back(new ScopedFile(i->first, code)); scopedfiles.emplace_back(new ScopedFile(i->first, code));
// clear files list so only fileSettings are used
if (useFS)
filelist.clear();
ProcessExecutor executor(filelist, fileSettings, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
const unsigned int exitCode = executor.check(); const unsigned int exitCode = executor.check();
CppCheckExecutor::reportSuppressions(settings, false, files, *this); CppCheckExecutor::reportSuppressions(settings, settings.nomsg, false, filelist, fileSettings, *this);
return exitCode; return exitCode;
} }
@ -808,21 +882,34 @@ private:
ASSERT_EQUALS("", errout.str()); // <- no unmatched suppression reported for macro suppression ASSERT_EQUALS("", errout.str()); // <- no unmatched suppression reported for macro suppression
} }
void suppressionsSettings() { void suppressionsSettingsFiles() {
runChecks(&TestSuppressions::checkSuppression); runChecks(&TestSuppressions::checkSuppressionFiles);
} }
void suppressionsSettingsThreads() { static void suppressionsSettingsFS() {
runChecks(&TestSuppressions::checkSuppressionThreads); // TODO
// runChecks(&TestSuppressions::checkSuppressionFS);
}
void suppressionsSettingsThreadsFiles() {
runChecks(&TestSuppressions::checkSuppressionThreadsFiles);
}
void suppressionsSettingsThreadsFS() {
runChecks(&TestSuppressions::checkSuppressionThreadsFS);
} }
#if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) #if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
void suppressionsSettingsProcesses() { void suppressionsSettingsProcessesFiles() {
runChecks(&TestSuppressions::checkSuppressionProcesses); runChecks(&TestSuppressions::checkSuppressionProcessesFiles);
}
void suppressionsSettingsProcessesFS() {
runChecks(&TestSuppressions::checkSuppressionProcessesFS);
} }
#endif #endif
void suppressionsMultiFile() { void suppressionsMultiFileInternal(unsigned int (TestSuppressions::*check)(std::map<std::string, std::string> &f, const std::string &)) {
std::map<std::string, std::string> files; std::map<std::string, std::string> files;
files["abc.cpp"] = "void f() {\n" files["abc.cpp"] = "void f() {\n"
"}\n"; "}\n";
@ -832,10 +919,18 @@ private:
"}\n"; "}\n";
// suppress uninitvar for this file and line // suppress uninitvar for this file and line
ASSERT_EQUALS(0, checkSuppression(files, "uninitvar:xyz.cpp:3")); ASSERT_EQUALS(0, (this->*check)(files, "uninitvar:xyz.cpp:3"));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void suppressionsMultiFileFiles() {
suppressionsMultiFileInternal(&TestSuppressions::checkSuppressionFiles);
}
void suppressionsMultiFileFS() {
suppressionsMultiFileInternal(&TestSuppressions::checkSuppressionFS);
}
void suppressionsPathSeparator() const { void suppressionsPathSeparator() const {
const Suppressions::Suppression s1("*", "test/foo/*"); const Suppressions::Suppression s1("*", "test/foo/*");
ASSERT_EQUALS(true, s1.isSuppressed(errorMessage("someid", "test/foo/bar.cpp", 142))); ASSERT_EQUALS(true, s1.isSuppressed(errorMessage("someid", "test/foo/bar.cpp", 142)));
@ -928,24 +1023,32 @@ private:
ASSERT_EQUALS(badSuppressionAttribute, msg); ASSERT_EQUALS(badSuppressionAttribute, msg);
} }
void inlinesuppress_symbolname() { void inlinesuppress_symbolname_Internal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) {
ASSERT_EQUALS(0, checkSuppression("void f() {\n" ASSERT_EQUALS(0, (this->*check)("void f() {\n"
" int a;\n" " int a;\n"
" /* cppcheck-suppress uninitvar symbolName=a */\n" " /* cppcheck-suppress uninitvar symbolName=a */\n"
" a++;\n" " a++;\n"
"}\n", "}\n",
"")); ""));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS(1, checkSuppression("void f() {\n" ASSERT_EQUALS(1, (this->*check)("void f() {\n"
" int a,b;\n" " int a,b;\n"
" /* cppcheck-suppress uninitvar symbolName=b */\n" " /* cppcheck-suppress uninitvar symbolName=b */\n"
" a++; b++;\n" " a++; b++;\n"
"}\n", "}\n",
"")); ""));
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
} }
void inlinesuppress_symbolname_Files() {
inlinesuppress_symbolname_Internal(&TestSuppressions::checkSuppressionFiles);
}
void inlinesuppress_symbolname_FS() {
inlinesuppress_symbolname_Internal(&TestSuppressions::checkSuppressionFS);
}
void inlinesuppress_comment() const { void inlinesuppress_comment() const {
Suppressions::Suppression s; Suppressions::Suppression s;
std::string errMsg; std::string errMsg;
@ -1141,14 +1244,22 @@ private:
ASSERT_EQUALS("",errout.str()); ASSERT_EQUALS("",errout.str());
} }
void suppressingSyntaxErrors() { // syntaxErrors should be suppressible (#7076) void suppressingSyntaxErrorsInternal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) { // syntaxErrors should be suppressible (#7076)
const char code[] = "if if\n"; const char code[] = "if if\n";
ASSERT_EQUALS(0, checkSuppression(code, "syntaxError:test.cpp:1")); ASSERT_EQUALS(0, (this->*check)(code, "syntaxError:test.cpp:1"));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void suppressingSyntaxErrorsInline() { // syntaxErrors should be suppressible (#5917) void suppressingSyntaxErrorsFiles() {
suppressingSyntaxErrorsInternal(&TestSuppressions::checkSuppressionFiles);
}
void suppressingSyntaxErrorsFS() {
suppressingSyntaxErrorsInternal(&TestSuppressions::checkSuppressionFiles);
}
void suppressingSyntaxErrorsInlineInternal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) { // syntaxErrors should be suppressible (#5917)
const char code[] = "double result(0.0);\n" const char code[] = "double result(0.0);\n"
"_asm\n" "_asm\n"
"{\n" "{\n"
@ -1159,11 +1270,19 @@ private:
" fstp QWORD PTR result ; store a double (8 bytes)\n" " fstp QWORD PTR result ; store a double (8 bytes)\n"
" pop EAX ; restore EAX\n" " pop EAX ; restore EAX\n"
"}"; "}";
ASSERT_EQUALS(0, checkSuppression(code, "")); ASSERT_EQUALS(0, (this->*check)(code, ""));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void suppressingSyntaxErrorsWhileFileRead() { // syntaxError while file read should be suppressible (PR #1333) void suppressingSyntaxErrorsInlineFiles() {
suppressingSyntaxErrorsInlineInternal(&TestSuppressions::checkSuppressionFiles);
}
void suppressingSyntaxErrorsInlineFS() {
suppressingSyntaxErrorsInlineInternal(&TestSuppressions::checkSuppressionFS);
}
void suppressingSyntaxErrorsWhileFileReadInternal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) { // syntaxError while file read should be suppressible (PR #1333)
const char code[] = "CONST (genType, KS_CONST) genService[KS_CFG_NR_OF_NVM_BLOCKS] =\n" const char code[] = "CONST (genType, KS_CONST) genService[KS_CFG_NR_OF_NVM_BLOCKS] =\n"
"{\n" "{\n"
"[!VAR \"BC\" = \"$BC + 1\"!][!//\n" "[!VAR \"BC\" = \"$BC + 1\"!][!//\n"
@ -1177,10 +1296,18 @@ private:
"[!VAR \"BC\" = \"$BC + 1\"!][!//\n" "[!VAR \"BC\" = \"$BC + 1\"!][!//\n"
"[!ENDIF!][!//\n" "[!ENDIF!][!//\n"
"};"; "};";
ASSERT_EQUALS(0, checkSuppression(code, "syntaxError:test.cpp:4")); ASSERT_EQUALS(0, (this->*check)(code, "syntaxError:test.cpp:4"));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void suppressingSyntaxErrorsWhileFileReadFiles() {
suppressingSyntaxErrorsWhileFileReadInternal(&TestSuppressions::checkSuppressionFiles);
}
void suppressingSyntaxErrorsWhileFileReadFS() {
suppressingSyntaxErrorsWhileFileReadInternal(&TestSuppressions::checkSuppressionFiles);
}
void symbol() const { void symbol() const {
Suppressions::Suppression s; Suppressions::Suppression s;
s.errorId = "foo"; s.errorId = "foo";
@ -1204,27 +1331,28 @@ private:
ASSERT_EQUALS(true, s.isSuppressed(errorMsg)); ASSERT_EQUALS(true, s.isSuppressed(errorMsg));
} }
void unusedFunction() { void unusedFunctionInternal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) {
ASSERT_EQUALS(0, checkSuppression("void f() {}", "unusedFunction")); ASSERT_EQUALS(0, (this->*check)("void f() {}", "unusedFunction"));
} }
void suppressingSyntaxErrorAndExitCode() { void unusedFunctionFiles() {
unusedFunctionInternal(&TestSuppressions::checkSuppressionFiles);
}
void unusedFunctionFS() {
unusedFunctionInternal(&TestSuppressions::checkSuppressionFS);
}
void suppressingSyntaxErrorAndExitCodeInternal(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) {
const char code[] = "fi if;"; const char code[] = "fi if;";
ASSERT_EQUALS(0, checkSuppression(code, "*:test.cpp")); ASSERT_EQUALS(0, (this->*check)(code, "*:test.cpp"));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// multi files, but only suppression one
std::map<std::string, std::string> mfiles;
mfiles["test.cpp"] = "fi if;";
mfiles["test2.cpp"] = "fi if";
ASSERT_EQUALS(2, checkSuppression(mfiles, "*:test.cpp"));
ASSERT_EQUALS("[test2.cpp:1]: (error) syntax error\n", errout.str());
// multi error in file, but only suppression one error // multi error in file, but only suppression one error
const char code2[] = "fi fi\n" const char code2[] = "fi fi\n"
"if if;"; "if if;";
ASSERT_EQUALS(2, checkSuppression(code2, "*:test.cpp:1")); // suppress all error at line 1 of test.cpp ASSERT_EQUALS(2, (this->*check)(code2, "*:test.cpp:1")); // suppress all error at line 1 of test.cpp
ASSERT_EQUALS("[test.cpp:2]: (error) syntax error\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (error) syntax error\n", errout.str());
// multi error in file, but only suppression one error (2) // multi error in file, but only suppression one error (2)
@ -1233,7 +1361,34 @@ private:
" int b = y/0;\n" " int b = y/0;\n"
"}\n" "}\n"
"f(0, 1);\n"; "f(0, 1);\n";
ASSERT_EQUALS(2, checkSuppression(code3, "zerodiv:test.cpp:3")); // suppress 'errordiv' at line 3 of test.cpp ASSERT_EQUALS(2, (this->*check)(code3, "zerodiv:test.cpp:3")); // suppress 'errordiv' at line 3 of test.cpp
}
void suppressingSyntaxErrorAndExitCodeFiles() {
suppressingSyntaxErrorAndExitCodeInternal(&TestSuppressions::checkSuppressionFiles);
}
static void suppressingSyntaxErrorAndExitCodeFS() {
// TODO
// suppressingSyntaxErrorAndExitCodeInternal(&TestSuppressions::checkSuppressionFS);
}
void suppressingSyntaxErrorAndExitCodeMultiFileInternal(unsigned int (TestSuppressions::*check)(std::map<std::string, std::string> &f, const std::string &)) {
// multi files, but only suppression one
std::map<std::string, std::string> mfiles;
mfiles["test.cpp"] = "fi if;";
mfiles["test2.cpp"] = "fi if";
ASSERT_EQUALS(2, (this->*check)(mfiles, "*:test.cpp"));
ASSERT_EQUALS("[test2.cpp:1]: (error) syntax error\n", errout.str());
}
void suppressingSyntaxErrorAndExitCodeMultiFileFiles() {
suppressingSyntaxErrorAndExitCodeMultiFileInternal(&TestSuppressions::checkSuppressionFiles);
}
static void suppressingSyntaxErrorAndExitCodeMultiFileFS() {
// TODO
// suppressingSyntaxErrorAndExitCodeMultiFileInternal(&TestSuppressions::checkSuppressionFS);
} }
void suppressLocal() const { void suppressLocal() const {