avoid some redundant and unused settings in tests among other cleanups / added and used `WARN_UNUSED` attribute (#5284)

This commit is contained in:
Oliver Stöneberg 2023-08-09 12:43:55 +02:00 committed by GitHub
parent 8166bfc7b8
commit 2502897265
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 85 additions and 55 deletions

View File

@ -79,6 +79,13 @@
# define UNUSED # define UNUSED
#endif #endif
// warn_unused
#if (defined(__clang__) && (__clang_major__ >= 15))
# define WARN_UNUSED [[gnu::warn_unused]]
#else
# define WARN_UNUSED
#endif
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type #define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
#include <string> #include <string>

View File

@ -90,7 +90,7 @@ public:
* to pass individual values to functions or constructors now or in the * to pass individual values to functions or constructors now or in the
* future when we might have even more detailed settings. * future when we might have even more detailed settings.
*/ */
class CPPCHECKLIB Settings { class CPPCHECKLIB WARN_UNUSED Settings {
private: private:
/** @brief terminate checking */ /** @brief terminate checking */

View File

@ -399,6 +399,8 @@ void TestFixture::setTemplateFormat(const std::string &templateFormat)
} }
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char lib[]) { TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char lib[]) {
if (REDUNDANT_CHECK && std::find(settings.libraries.cbegin(), settings.libraries.cend(), lib) != settings.libraries.cend())
throw std::runtime_error("redundant setting: libraries (" + std::string(lib) + ")");
// TODO: exename is not yet set // TODO: exename is not yet set
LOAD_LIB_2_EXE(settings.library, lib, fixture.exename.c_str()); LOAD_LIB_2_EXE(settings.library, lib, fixture.exename.c_str());
// strip extension // strip extension
@ -414,6 +416,11 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char l
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(cppcheck::Platform::Type type) TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(cppcheck::Platform::Type type)
{ {
const std::string platformStr = cppcheck::Platform::toString(type); const std::string platformStr = cppcheck::Platform::toString(type);
// TODO: the default platform differs between Windows and Linux
//if (REDUNDANT_CHECK && settings.platform.type == type)
// throw std::runtime_error("redundant setting: platform (" + platformStr + ")");
std::string errstr; std::string errstr;
// TODO: exename is not yet set // TODO: exename is not yet set
if (!settings.platform.set(platformStr, errstr, {fixture.exename})) if (!settings.platform.set(platformStr, errstr, {fixture.exename}))

View File

@ -130,7 +130,6 @@ protected:
check.runChecks(tokenizer, settings, errorLogger); check.runChecks(tokenizer, settings, errorLogger);
} }
// TODO: bail out on redundant settings
class SettingsBuilder class SettingsBuilder
{ {
public: public:
@ -138,41 +137,59 @@ protected:
SettingsBuilder(const TestFixture &fixture, Settings settings) : fixture(fixture), settings(std::move(settings)) {} SettingsBuilder(const TestFixture &fixture, Settings settings) : fixture(fixture), settings(std::move(settings)) {}
SettingsBuilder& severity(Severity::SeverityType sev, bool b = true) { SettingsBuilder& severity(Severity::SeverityType sev, bool b = true) {
if (REDUNDANT_CHECK && settings.severity.isEnabled(sev) == b)
throw std::runtime_error("redundant setting: severity");
settings.severity.setEnabled(sev, b); settings.severity.setEnabled(sev, b);
return *this; return *this;
} }
SettingsBuilder& certainty(Certainty cert, bool b = true) { SettingsBuilder& certainty(Certainty cert, bool b = true) {
if (REDUNDANT_CHECK && settings.certainty.isEnabled(cert) == b)
throw std::runtime_error("redundant setting: certainty");
settings.certainty.setEnabled(cert, b); settings.certainty.setEnabled(cert, b);
return *this; return *this;
} }
SettingsBuilder& clang() { SettingsBuilder& clang() {
if (REDUNDANT_CHECK && settings.clang)
throw std::runtime_error("redundant setting: clang");
settings.clang = true; settings.clang = true;
return *this; return *this;
} }
SettingsBuilder& checkLibrary() { SettingsBuilder& checkLibrary() {
if (REDUNDANT_CHECK && settings.checkLibrary)
throw std::runtime_error("redundant setting: checkLibrary");
settings.checkLibrary = true; settings.checkLibrary = true;
return *this; return *this;
} }
SettingsBuilder& checkUnusedTemplates(bool b = true) { SettingsBuilder& checkUnusedTemplates(bool b = true) {
if (REDUNDANT_CHECK && settings.checkUnusedTemplates == b)
throw std::runtime_error("redundant setting: checkUnusedTemplates");
settings.checkUnusedTemplates = b; settings.checkUnusedTemplates = b;
return *this; return *this;
} }
SettingsBuilder& debugwarnings(bool b = true) { SettingsBuilder& debugwarnings(bool b = true) {
if (REDUNDANT_CHECK && settings.debugwarnings == b)
throw std::runtime_error("redundant setting: debugwarnings");
settings.debugwarnings = b; settings.debugwarnings = b;
return *this; return *this;
} }
SettingsBuilder& c(Standards::cstd_t std) { SettingsBuilder& c(Standards::cstd_t std) {
// TODO: CLatest and C11 are the same - handle differently
//if (REDUNDANT_CHECK && settings.standards.c == std)
// throw std::runtime_error("redundant setting: standards.c");
settings.standards.c = std; settings.standards.c = std;
return *this; return *this;
} }
SettingsBuilder& cpp(Standards::cppstd_t std) { SettingsBuilder& cpp(Standards::cppstd_t std) {
// TODO: CPPLatest and CPP20 are the same - handle differently
//if (REDUNDANT_CHECK && settings.standards.cpp == std)
// throw std::runtime_error("redundant setting: standards.cpp");
settings.standards.cpp = std; settings.standards.cpp = std;
return *this; return *this;
} }
@ -184,11 +201,15 @@ protected:
SettingsBuilder& platform(cppcheck::Platform::Type type); SettingsBuilder& platform(cppcheck::Platform::Type type);
SettingsBuilder& checkConfiguration() { SettingsBuilder& checkConfiguration() {
if (REDUNDANT_CHECK && settings.checkConfiguration)
throw std::runtime_error("redundant setting: checkConfiguration");
settings.checkConfiguration = true; settings.checkConfiguration = true;
return *this; return *this;
} }
SettingsBuilder& checkHeaders(bool b = true) { SettingsBuilder& checkHeaders(bool b = true) {
if (REDUNDANT_CHECK && settings.checkHeaders == b)
throw std::runtime_error("redundant setting: checkHeaders");
settings.checkHeaders = b; settings.checkHeaders = b;
return *this; return *this;
} }
@ -199,6 +220,8 @@ protected:
private: private:
const TestFixture &fixture; const TestFixture &fixture;
Settings settings; Settings settings;
const bool REDUNDANT_CHECK = false;
}; };
SettingsBuilder settingsBuilder() const { SettingsBuilder settingsBuilder() const {

View File

@ -76,7 +76,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
const Settings settings = settingsBuilder(settings0).severity(Severity::style).severity(Severity::warning).severity(Severity::portability).severity(Severity::performance) const Settings settings = settingsBuilder(settings0).severity(Severity::performance)
.c(Standards::CLatest).cpp(Standards::CPPLatest).certainty(Certainty::inconclusive).build(); .c(Standards::CLatest).cpp(Standards::CPPLatest).certainty(Certainty::inconclusive).build();
// Raw tokens.. // Raw tokens..

View File

@ -39,7 +39,7 @@ public:
private: private:
Settings settings0 = settingsBuilder().severity(Severity::style).library("std.cfg").build(); Settings settings0 = settingsBuilder().severity(Severity::style).library("std.cfg").build();
Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build(); const Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build();
void run() override { void run() override {
TEST_CASE(virtualDestructor1); // Base class not found => no error TEST_CASE(virtualDestructor1); // Base class not found => no error

View File

@ -127,7 +127,7 @@ private:
TEST_CASE(knownConditionIncrementLoop); // #9808 TEST_CASE(knownConditionIncrementLoop); // #9808
} }
void check(const char code[], Settings &settings, const char* filename = "test.cpp") { void check(const char code[], const Settings &settings, const char* filename = "test.cpp") {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
@ -154,7 +154,7 @@ private:
} }
void check(const char code[], const char* filename = "test.cpp", bool inconclusive = false) { void check(const char code[], const char* filename = "test.cpp", bool inconclusive = false) {
Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build(); const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
check(code, settings, filename); check(code, settings, filename);
} }
@ -5645,7 +5645,7 @@ private:
} }
void compareOutOfTypeRange() { void compareOutOfTypeRange() {
Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build(); const Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build();
check("void f(unsigned char c) {\n" check("void f(unsigned char c) {\n"
" if (c == 256) {}\n" " if (c == 256) {}\n"

View File

@ -63,7 +63,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings1 = settingsBuilder(s ? *s : settings).certainty(Certainty::inconclusive, inconclusive).build(); const Settings settings1 = settingsBuilder(s ? *s : settings).certainty(Certainty::inconclusive, inconclusive).build();
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this);
@ -397,7 +397,7 @@ private:
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n" ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n"
"[test.cpp:6] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n", errout.str()); "[test.cpp:6] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n", errout.str());
const Settings s = settingsBuilder(settings).library("gnu.cfg").build(); const Settings s = settingsBuilder().library("gnu.cfg").build();
check(code, true, &s); check(code, true, &s);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }

View File

@ -1562,18 +1562,21 @@ private:
{ {
const char code[] = "int main(void) {}"; const char code[] = "int main(void) {}";
Settings s; {
const Settings s = settingsBuilder().c(Standards::C89).build();
s.standards.c = Standards::C89; check(code, "test.c", &s); // c code (c89)
check(code, "test.c", &s); // c code (c89) ASSERT_EQUALS("[test.c:1]: (error) Found an exit path from function with non-void return type that has missing return statement\n", errout.str());
ASSERT_EQUALS("[test.c:1]: (error) Found an exit path from function with non-void return type that has missing return statement\n", errout.str()); }
s.standards.c = Standards::C99; {
check(code, "test.c", &s); // c code (c99) const Settings s = settingsBuilder().c(Standards::C99).build();
ASSERT_EQUALS("", errout.str()); check(code, "test.c", &s); // c code (c99)
ASSERT_EQUALS("", errout.str());
check(code, "test.cpp", &s); // c++ code check(code, "test.cpp", &s); // c++ code
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
}
} }
check("F(A,B) { x=1; }"); check("F(A,B) { x=1; }");
@ -1825,9 +1828,8 @@ private:
} }
void checkLibraryMatchFunctions() { void checkLibraryMatchFunctions() {
Settings s = settingsBuilder(settings).checkLibrary().build(); Settings s = settingsBuilder(settings).checkLibrary().debugwarnings().build();
s.daca = true; s.daca = true;
s.debugwarnings = true;
check("void f() {\n" check("void f() {\n"
" lib_func();" " lib_func();"

View File

@ -474,7 +474,7 @@ private:
} }
void assign23() { void assign23() {
const Settings s = settingsBuilder(settings).library("posix.cfg").build(); const Settings s = settingsBuilder().library("posix.cfg").build();
check("void f() {\n" check("void f() {\n"
" int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14;\n" " int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14;\n"
" *&n1 = open(\"xx.log\", O_RDONLY);\n" " *&n1 = open(\"xx.log\", O_RDONLY);\n"
@ -2764,8 +2764,6 @@ private:
} }
void functionCallCastConfig() { // #9652 void functionCallCastConfig() { // #9652
Settings settingsFunctionCall = settings;
const char xmldata[] = "<?xml version=\"1.0\"?>\n" const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def format=\"2\">\n" "<def format=\"2\">\n"
" <function name=\"free_func\">\n" " <function name=\"free_func\">\n"
@ -2778,7 +2776,8 @@ private:
" </arg>\n" " </arg>\n"
" </function>\n" " </function>\n"
"</def>"; "</def>";
ASSERT(settingsFunctionCall.library.loadxmldata(xmldata, sizeof(xmldata))); const Settings settingsFunctionCall = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build();
check("void test_func()\n" check("void test_func()\n"
"{\n" "{\n"
" char * buf = malloc(4);\n" " char * buf = malloc(4);\n"
@ -2810,7 +2809,7 @@ private:
" <arg nr=\"1\" direction=\"in\"/>\n" " <arg nr=\"1\" direction=\"in\"/>\n"
" </function>\n" " </function>\n"
"</def>\n"; "</def>\n";
const Settings settingsLeakIgnore = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build(); const Settings settingsLeakIgnore = settingsBuilder().libraryxml(xmldata, sizeof(xmldata)).build();
check("void f() {\n" check("void f() {\n"
" double* a = new double[1024];\n" " double* a = new double[1024];\n"
" SomeClass::someMethod(a);\n" " SomeClass::someMethod(a);\n"

View File

@ -77,12 +77,13 @@ private:
} }
} }
settings.jobs = jobs; Settings s = settings;
settings.showtime = opt.showtime; s.jobs = jobs;
s.showtime = opt.showtime;
if (opt.plistOutput) if (opt.plistOutput)
settings.plistOutput = opt.plistOutput; s.plistOutput = opt.plistOutput;
// TODO: test with settings.project.fileSettings; // TODO: test with settings.project.fileSettings;
ProcessExecutor executor(filemap, settings, settings.nomsg, *this); ProcessExecutor executor(filemap, s, s.nomsg, *this);
std::vector<std::unique_ptr<ScopedFile>> scopedfiles; std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
scopedfiles.reserve(filemap.size()); scopedfiles.reserve(filemap.size());
for (std::map<std::string, std::size_t>::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i) for (std::map<std::string, std::size_t>::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)

View File

@ -38,7 +38,7 @@ public:
private: private:
// If there are unused templates, keep those // If there are unused templates, keep those
const Settings settings = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build(); const Settings settings = settingsBuilder().severity(Severity::portability).build();
void run() override { void run() override {
TEST_CASE(template1); TEST_CASE(template1);

View File

@ -34,11 +34,10 @@ public:
private: private:
// If there are unused templates, keep those const Settings settings0 = settingsBuilder().severity(Severity::portability).build();
const Settings settings0 = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build(); const Settings settings1 = settingsBuilder().severity(Severity::style).build();
const Settings settings1 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build(); const Settings settings_std = settingsBuilder().library("std.cfg").build();
const Settings settings_std = settingsBuilder().library("std.cfg").checkUnusedTemplates().build(); const Settings settings_windows = settingsBuilder().library("windows.cfg").severity(Severity::portability).build();
const Settings settings_windows = settingsBuilder().library("windows.cfg").severity(Severity::portability).checkUnusedTemplates().build();
void run() override { void run() override {
TEST_CASE(combine_strings); TEST_CASE(combine_strings);

View File

@ -40,10 +40,8 @@ public:
private: private:
// If there are unused templates, keep those const Settings settings0 = settingsBuilder().severity(Severity::style).build();
const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build(); const Settings settings1 = settingsBuilder().severity(Severity::portability).build();
const Settings settings1 = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build();
const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
void run() override { void run() override {
TEST_CASE(c1); TEST_CASE(c1);
@ -285,7 +283,7 @@ private:
errout.str(""); errout.str("");
// Tokenize.. // Tokenize..
// show warnings about unhandled typedef // show warnings about unhandled typedef
const Settings settings = settingsBuilder(settings2).certainty(Certainty::inconclusive).debugwarnings().build(); const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings().build();
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
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

@ -39,10 +39,7 @@ public:
private: private:
// If there are unused templates, keep those const Settings settings0 = settingsBuilder().severity(Severity::style).build();
const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
const Settings settings1 = settingsBuilder().checkUnusedTemplates().build();
const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
void run() override { void run() override {
TEST_CASE(simplifyUsing1); TEST_CASE(simplifyUsing1);

View File

@ -68,9 +68,8 @@ public:
private: private:
const Token* vartok{nullptr}; const Token* vartok{nullptr};
const Token* typetok{nullptr}; const Token* typetok{nullptr};
// If there are unused templates, keep those Settings settings1 = settingsBuilder().library("std.cfg").build();
Settings settings1 = settingsBuilder().library("std.cfg").checkUnusedTemplates().build(); const Settings settings2 = settingsBuilder().platform(cppcheck::Platform::Type::Unspecified).build();
const Settings settings2 = settingsBuilder().checkUnusedTemplates().platform(cppcheck::Platform::Type::Unspecified).build();
void reset() { void reset() {
vartok = nullptr; vartok = nullptr;

View File

@ -44,11 +44,9 @@ public:
TestTokenizer() : TestFixture("TestTokenizer") {} TestTokenizer() : TestFixture("TestTokenizer") {}
private: private:
// If there are unused templates, keep those const Settings settings0 = settingsBuilder().library("qt.cfg").build();
const Settings settings0 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build(); const Settings settings1 = settingsBuilder().library("qt.cfg").library("std.cfg").build();
const Settings settings1 = settingsBuilder().library("qt.cfg").library("std.cfg").checkUnusedTemplates().build(); const Settings settings_windows = settingsBuilder().library("windows.cfg").build();
const Settings settings2 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
const Settings settings_windows = settingsBuilder().library("windows.cfg").checkUnusedTemplates().build();
void run() override { void run() override {
TEST_CASE(tokenize1); TEST_CASE(tokenize1);
@ -522,7 +520,7 @@ private:
std::string tokenizeDebugListing_(const char* file, int line, const char code[], const char filename[] = "test.cpp") { std::string tokenizeDebugListing_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
errout.str(""); errout.str("");
const Settings settings = settingsBuilder(settings2).c(Standards::C89).cpp(Standards::CPP03).build(); const Settings settings = settingsBuilder(settings0).c(Standards::C89).cpp(Standards::CPP03).build();
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
@ -946,7 +944,7 @@ private:
} }
{ {
const Settings s = settingsBuilder().checkUnusedTemplates().build(); const Settings s;
ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n" ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n"
"class Foo {\n" "class Foo {\n"
"public:\n" "public:\n"

View File

@ -34,7 +34,7 @@ public:
TestVarID() : TestFixture("TestVarID") {} TestVarID() : TestFixture("TestVarID") {}
private: private:
Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).checkUnusedTemplates().platform(cppcheck::Platform::Type::Unix64).build(); const Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).platform(cppcheck::Platform::Type::Unix64).build();
void run() override { void run() override {
TEST_CASE(varid1); TEST_CASE(varid1);
TEST_CASE(varid2); TEST_CASE(varid2);