testrunner: more `SettingsBuilder` usage and `const` cleanups (#5026)

This commit is contained in:
Oliver Stöneberg 2023-05-02 15:54:19 +02:00 committed by GitHub
parent 05d72b806d
commit 25183ff484
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 285 additions and 326 deletions

View File

@ -411,3 +411,13 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char l
settings.libraries.emplace_back(lib_s); settings.libraries.emplace_back(lib_s);
return *this; return *this;
} }
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(cppcheck::Platform::Type type)
{
const std::string platformStr = cppcheck::Platform::toString(type);
std::string errstr;
// TODO: exename is not yet set
if (!settings.platform.set(platformStr, errstr, {fixture.exename}))
throw std::runtime_error("platform '" + platformStr + "' not found");
return *this;
}

View File

@ -134,8 +134,8 @@ protected:
explicit SettingsBuilder(const TestFixture &fixture) : fixture(fixture) {} explicit SettingsBuilder(const TestFixture &fixture) : fixture(fixture) {}
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) { SettingsBuilder& severity(Severity::SeverityType sev, bool b = true) {
settings.severity.enable(sev); settings.severity.setEnabled(sev, b);
return *this; return *this;
} }
@ -154,8 +154,8 @@ protected:
return *this; return *this;
} }
SettingsBuilder& checkUnusedTemplates() { SettingsBuilder& checkUnusedTemplates(bool b = true) {
settings.checkUnusedTemplates = true; settings.checkUnusedTemplates = b;
return *this; return *this;
} }
@ -176,6 +176,18 @@ protected:
SettingsBuilder& library(const char lib[]); SettingsBuilder& library(const char lib[]);
SettingsBuilder& platform(cppcheck::Platform::Type type);
SettingsBuilder& checkConfiguration() {
settings.checkConfiguration = true;
return *this;
}
SettingsBuilder& checkHeaders(bool b = true) {
settings.checkHeaders = b;
return *this;
}
Settings build() { Settings build() {
return std::move(settings); return std::move(settings);
} }

View File

@ -383,8 +383,7 @@ private:
const char* file, const char* file,
int line) int line)
{ {
Settings settings; const Settings settings = settingsBuilder().library("std.cfg").build();
LOAD_LIB_2(settings.library, "std.cfg");
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

@ -77,14 +77,8 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings = settings0; const Settings settings = settingsBuilder(settings0).severity(Severity::style).severity(Severity::warning).severity(Severity::portability).severity(Severity::performance)
settings.severity.enable(Severity::style); .c(Standards::CLatest).cpp(Standards::CPPLatest).certainty(Certainty::inconclusive).build();
settings.severity.enable(Severity::warning);
settings.severity.enable(Severity::portability);
settings.severity.enable(Severity::performance);
settings.standards.c = Standards::CLatest;
settings.standards.cpp = Standards::CPPLatest;
settings.certainty.enable(Certainty::inconclusive);
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, filename); std::vector<std::string> files(1, filename);

View File

@ -31,11 +31,9 @@ public:
TestCharVar() : TestFixture("TestCharVar") {} TestCharVar() : TestFixture("TestCharVar") {}
private: private:
Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).build(); const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).platform(cppcheck::Platform::Type::Unspecified).build();
void run() override { void run() override {
PLATFORM(settings.platform, cppcheck::Platform::Type::Unspecified);
TEST_CASE(array_index_1); TEST_CASE(array_index_1);
TEST_CASE(array_index_2); TEST_CASE(array_index_2);
TEST_CASE(bitop); TEST_CASE(bitop);

View File

@ -1048,11 +1048,7 @@ private:
#define GET_SYMBOL_DB(AST) \ #define GET_SYMBOL_DB(AST) \
Settings settings = settingsBuilder().clang().build(); \ const Settings settings = settingsBuilder().clang().platform(cppcheck::Platform::Type::Unix64).build(); \
{ \
std::string errstr; \
ASSERT_EQUALS_MSG(true, settings.platform.set("unix64", errstr, {exename.c_str()}), errstr); \
} \
Tokenizer tokenizer(&settings, this); \ Tokenizer tokenizer(&settings, this); \
{ \ { \
std::istringstream istr(AST); \ std::istringstream istr(AST); \

View File

@ -259,7 +259,7 @@ private:
void checkCopyCtorAndEqOperator_(const char code[], const char* file, int line) { void checkCopyCtorAndEqOperator_(const char code[], const char* file, int line) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Settings settings = settingsBuilder().severity(Severity::warning).build(); const Settings settings = settingsBuilder().severity(Severity::warning).build();
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);
@ -2570,6 +2570,7 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
// TODO: subsequent tests depend on these changes - should use SettingsBuilder
settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings0.severity.enable(Severity::warning); settings0.severity.enable(Severity::warning);
@ -2886,7 +2887,7 @@ private:
#define checkNoMemset(...) checkNoMemset_(__FILE__, __LINE__, __VA_ARGS__) #define checkNoMemset(...) checkNoMemset_(__FILE__, __LINE__, __VA_ARGS__)
void checkNoMemset_(const char* file, int line, const char code[]) { void checkNoMemset_(const char* file, int line, const char code[]) {
Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).build(); const Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability).build();
checkNoMemset_(file, line, code, settings); checkNoMemset_(file, line, code, settings);
} }
@ -3150,7 +3151,7 @@ private:
errout.str()); errout.str());
// #1655 // #1655
Settings s = settingsBuilder().library("std.cfg").build(); const Settings s = settingsBuilder().library("std.cfg").build();
checkNoMemset("void f() {\n" checkNoMemset("void f() {\n"
" char c[] = \"abc\";\n" " char c[] = \"abc\";\n"
" std::string s;\n" " std::string s;\n"
@ -3557,23 +3558,20 @@ private:
} }
#define checkConst(...) checkConst_(__FILE__, __LINE__, __VA_ARGS__) #define checkConst(...) checkConst_(__FILE__, __LINE__, __VA_ARGS__)
void checkConst_(const char* file, int line, const char code[], Settings *s = nullptr, bool inconclusive = true) { void checkConst_(const char* file, int line, const char code[], const Settings *s = nullptr, bool inconclusive = true) {
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
// Check.. const Settings settings = settingsBuilder(s ? *s : settings0).certainty(Certainty::inconclusive, inconclusive).build();
if (!s)
s = &settings0;
s->certainty.setEnabled(Certainty::inconclusive, inconclusive);
Preprocessor preprocessor(*s); Preprocessor preprocessor(settings);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(s, this, &preprocessor); 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.checkConst)(); (checkClass.checkConst)();
} }
@ -7224,7 +7222,7 @@ private:
} }
void qualifiedNameMember() { // #10872 void qualifiedNameMember() { // #10872
Settings s = settingsBuilder().severity(Severity::style).debugwarnings().library("std.cfg").build(); const Settings s = settingsBuilder().severity(Severity::style).debugwarnings().library("std.cfg").build();
checkConst("struct data {};\n" checkConst("struct data {};\n"
" struct S {\n" " struct S {\n"
" std::vector<data> std;\n" " std::vector<data> std;\n"
@ -7279,7 +7277,7 @@ private:
errout.str(""); errout.str("");
// Check.. // Check..
Settings settings = settingsBuilder().severity(Severity::performance).build(); const Settings settings = settingsBuilder().severity(Severity::performance).build();
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);
@ -7609,9 +7607,7 @@ private:
errout.str(""); errout.str("");
// Check.. // Check..
Settings settings; const Settings settings = settingsBuilder().severity(Severity::warning).certainty(Certainty::inconclusive, inconclusive).build();
settings.severity.enable(Severity::warning);
settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);
@ -7960,7 +7956,7 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Settings settings = settingsBuilder().severity(Severity::style).build(); const Settings settings = settingsBuilder().severity(Severity::style).build();
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);

View File

@ -39,14 +39,10 @@ public:
TestCondition() : TestFixture("TestCondition") {} TestCondition() : TestFixture("TestCondition") {}
private: private:
Settings settings0 = settingsBuilder().library("qt.cfg").library("std.cfg").severity(Severity::style).severity(Severity::warning).build(); const Settings settings0 = settingsBuilder().library("qt.cfg").library("std.cfg").severity(Severity::style).severity(Severity::warning).platform(cppcheck::Platform::Type::Native).build();
Settings settings1 = settingsBuilder().severity(Severity::style).severity(Severity::warning).build(); Settings settings1 = settingsBuilder().severity(Severity::style).severity(Severity::warning).platform(cppcheck::Platform::Type::Native).build();
void run() override { void run() override {
// known platform..
PLATFORM(settings0.platform, cppcheck::Platform::Type::Native);
PLATFORM(settings1.platform, cppcheck::Platform::Type::Native);
const char cfg[] = "<?xml version=\"1.0\"?>\n" const char cfg[] = "<?xml version=\"1.0\"?>\n"
"<def>\n" "<def>\n"
" <function name=\"bar\"> <pure/> </function>\n" " <function name=\"bar\"> <pure/> </function>\n"
@ -132,7 +128,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[], Settings &settings, const char* filename = "test.cpp") {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
@ -146,21 +142,21 @@ 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); Preprocessor preprocessor(settings);
preprocessor.setDirectives(tokens1); preprocessor.setDirectives(tokens1);
// Tokenizer.. // Tokenizer..
Tokenizer tokenizer(settings, this, &preprocessor); Tokenizer tokenizer(&settings, this, &preprocessor);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
// Run checks.. // Run checks..
runChecks<CheckCondition>(&tokenizer, settings, this); runChecks<CheckCondition>(&tokenizer, &settings, this);
} }
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) {
settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
check(code, &settings0, filename); check(code, settings, filename);
} }
void assignAndCompare() { void assignAndCompare() {
@ -5635,70 +5631,69 @@ private:
} }
void compareOutOfTypeRange() { void compareOutOfTypeRange() {
Settings settingsUnix64 = settingsBuilder().severity(Severity::style).build(); Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build();
PLATFORM(settingsUnix64.platform, cppcheck::Platform::Type::Unix64);
check("void f(unsigned char c) {\n" check("void f(unsigned char c) {\n"
" if (c == 256) {}\n" " if (c == 256) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str());
check("void f(unsigned char* b, int i) {\n" // #6372 check("void f(unsigned char* b, int i) {\n" // #6372
" if (b[i] == 256) {}\n" " if (b[i] == 256) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout.str());
check("void f(unsigned char c) {\n" check("void f(unsigned char c) {\n"
" if (c == 255) {}\n" " if (c == 255) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(bool b) {\n" check("void f(bool b) {\n"
" if (b == true) {}\n" " if (b == true) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #10372 // #10372
check("void f(signed char x) {\n" check("void f(signed char x) {\n"
" if (x == 0xff) {}\n" " if (x == 0xff) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false.\n", errout.str());
check("void f(short x) {\n" check("void f(short x) {\n"
" if (x == 0xffff) {}\n" " if (x == 0xffff) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false.\n", errout.str());
check("void f(int x) {\n" check("void f(int x) {\n"
" if (x == 0xffffffff) {}\n" " if (x == 0xffffffff) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(long x) {\n" check("void f(long x) {\n"
" if (x == ~0L) {}\n" " if (x == ~0L) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(long long x) {\n" check("void f(long long x) {\n"
" if (x == ~0LL) {}\n" " if (x == ~0LL) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int f(int x) {\n" check("int f(int x) {\n"
" const int i = 0xFFFFFFFF;\n" " const int i = 0xFFFFFFFF;\n"
" if (x == i) {}\n" " if (x == i) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f() {\n"
" char c;\n" " char c;\n"
" if ((c = foo()) != -1) {}\n" " if ((c = foo()) != -1) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(int x) {\n" check("void f(int x) {\n"
" if (x < 3000000000) {}\n" " if (x < 3000000000) {}\n"
"}", &settingsUnix64); "}", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout.str());
check("void f(const signed char i) {\n" // #8545 check("void f(const signed char i) {\n" // #8545
@ -5708,7 +5703,7 @@ private:
" if (i < +128) {}\n" // warn " if (i < +128) {}\n" // warn
" if (i <= +127) {}\n" // warn " if (i <= +127) {}\n" // warn
" if (i <= +126) {}\n" " if (i <= +126) {}\n"
"}\n", &settingsUnix64); "}\n", settingsUnix64);
ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'const signed char' against value -129. Condition is always true.\n" ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'const signed char' against value -129. Condition is always true.\n"
"[test.cpp:3]: (style) Comparing expression of type 'const signed char' against value -128. Condition is always true.\n" "[test.cpp:3]: (style) Comparing expression of type 'const signed char' against value -128. Condition is always true.\n"
"[test.cpp:5]: (style) Comparing expression of type 'const signed char' against value 128. Condition is always true.\n" "[test.cpp:5]: (style) Comparing expression of type 'const signed char' against value 128. Condition is always true.\n"
@ -5732,7 +5727,7 @@ private:
" if (255 > u) {}\n" " if (255 > u) {}\n"
" if (255 <= u) {}\n" " if (255 <= u) {}\n"
" if (255 >= u) {}\n" // warn " if (255 >= u) {}\n" // warn
"}\n", &settingsUnix64); "}\n", settingsUnix64);
ASSERT_EQUALS("[test.cpp:3]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n" ASSERT_EQUALS("[test.cpp:3]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n"
"[test.cpp:4]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n" "[test.cpp:4]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n"
"[test.cpp:6]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n" "[test.cpp:6]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n"

View File

@ -1493,6 +1493,7 @@ private:
} }
void initvar_private_constructor() { void initvar_private_constructor() {
const Settings settingsOld = settings;
settings.standards.cpp = Standards::CPP11; settings.standards.cpp = Standards::CPP11;
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
@ -1514,6 +1515,7 @@ private:
"Fred::Fred()\n" "Fred::Fred()\n"
"{ }"); "{ }");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
settings = settingsOld;
} }
void initvar_copy_constructor() { // ticket #1611 void initvar_copy_constructor() { // ticket #1611
@ -3111,8 +3113,7 @@ private:
} }
void uninitVarArray10() { // #11650 void uninitVarArray10() { // #11650
Settings s(settings); const Settings s = settingsBuilder(settings).library("std.cfg").build();
LOAD_LIB_2(s.library, "std.cfg");
check("struct T { int j; };\n" check("struct T { int j; };\n"
"struct U { int k{}; };\n" "struct U { int k{}; };\n"
"struct S {\n" "struct S {\n"

View File

@ -262,6 +262,7 @@ private:
"}", "test.c"); "}", "test.c");
ASSERT_EQUALS("[test.c:3]: (warning) Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead.\n", errout.str()); ASSERT_EQUALS("[test.c:3]: (warning) Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead.\n", errout.str());
const Settings settingsOld = settings;
settings.standards.c = Standards::C89; settings.standards.c = Standards::C89;
settings.standards.cpp = Standards::CPP03; settings.standards.cpp = Standards::CPP03;
check("void f()\n" check("void f()\n"
@ -281,8 +282,7 @@ private:
" char *x = alloca(10);\n" " char *x = alloca(10);\n"
"}", "test.c"); "}", "test.c");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
settings.standards.c = Standards::C11; settings = settingsOld;
settings.standards.cpp = Standards::CPP11;
} }
// ticket #3121 // ticket #3121
@ -1291,8 +1291,7 @@ private:
} }
void checkIgnoredReturnValue() { void checkIgnoredReturnValue() {
Settings settings2; Settings settings2 = settingsBuilder().severity(Severity::warning).build();
settings2.severity.enable(Severity::warning);
const char xmldata[] = "<?xml version=\"1.0\"?>\n" const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def version=\"2\">\n" "<def version=\"2\">\n"
" <function name=\"mystrcmp,foo::mystrcmp\">\n" " <function name=\"mystrcmp,foo::mystrcmp\">\n"
@ -1444,8 +1443,7 @@ private:
} }
void checkIgnoredErrorCode() { void checkIgnoredErrorCode() {
Settings settings2; Settings settings2 = settingsBuilder().severity(Severity::style).build();
settings2.addEnabled("style");
const char xmldata[] = "<?xml version=\"1.0\"?>\n" const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def version=\"2\">\n" "<def version=\"2\">\n"
" <function name=\"mystrcmp\">\n" " <function name=\"mystrcmp\">\n"

View File

@ -35,10 +35,9 @@ public:
TestGarbage() : TestFixture("TestGarbage") {} TestGarbage() : TestFixture("TestGarbage") {}
private: private:
Settings settings; Settings settings = settingsBuilder().debugwarnings().build();
void run() override { void run() override {
settings.debugwarnings = true;
settings.severity.fill(); settings.severity.fill();
settings.certainty.fill(); settings.certainty.fill();

View File

@ -87,6 +87,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
// TODO: using dedicated Settings (i.e. copying it) object causes major slowdown
settings1.severity.clear(); settings1.severity.clear();
settings1.severity.enable(Severity::warning); settings1.severity.enable(Severity::warning);
settings1.severity.enable(Severity::style); settings1.severity.enable(Severity::style);

View File

@ -240,19 +240,19 @@ private:
runChecks<CheckLeakAutoVar>(&tokenizer, &settings, this); runChecks<CheckLeakAutoVar>(&tokenizer, &settings, this);
} }
void check_(const char* file, int line, const char code[], Settings & settings_) { void check_(const char* file, int line, const char code[], const Settings & s) {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
const Settings settings0 = settingsBuilder(s).checkLibrary().build();
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings_, this); Tokenizer tokenizer(&settings0, 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);
settings_.checkLibrary = true;
// Check for leaks.. // Check for leaks..
runChecks<CheckLeakAutoVar>(&tokenizer, &settings_, this); runChecks<CheckLeakAutoVar>(&tokenizer, &settings0, this);
} }
void assign1() { void assign1() {
@ -469,7 +469,7 @@ private:
} }
void assign23() { void assign23() {
Settings s = settings; const Settings settingsOld = settings;
LOAD_LIB_2(settings.library, "posix.cfg"); LOAD_LIB_2(settings.library, "posix.cfg");
settings.libraries.emplace_back("posix"); settings.libraries.emplace_back("posix");
check("void f() {\n" check("void f() {\n"
@ -504,7 +504,7 @@ private:
"[test.cpp:17]: (error) Resource leak: n13\n" "[test.cpp:17]: (error) Resource leak: n13\n"
"[test.cpp:17]: (error) Resource leak: n14\n", "[test.cpp:17]: (error) Resource leak: n14\n",
errout.str()); errout.str());
settings = s; settings = settingsOld;
} }
void assign24() { void assign24() {
@ -1874,10 +1874,7 @@ private:
} }
void ifelse24() { // #1733 void ifelse24() { // #1733
Settings s; const Settings s = settingsBuilder().library("std.cfg").library("posix.cfg").build();
LOAD_LIB_2(s.library, "std.cfg");
LOAD_LIB_2(s.library, "posix.cfg");
s.libraries.emplace_back("posix");
check("void f() {\n" check("void f() {\n"
" char* temp = strdup(\"temp.txt\");\n" " char* temp = strdup(\"temp.txt\");\n"

View File

@ -1568,9 +1568,8 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings; // #5560 - set c++03
settings.severity.enable(Severity::style); const Settings settings = settingsBuilder().severity(Severity::style).cpp(Standards::CPP03).build();
settings.standards.cpp = Standards::CPP03; // #5560
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);
@ -1771,11 +1770,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings; Settings settings = settingsBuilder().severity(Severity::warning).severity(Severity::portability, portability).certainty(Certainty::inconclusive, inconclusive).build();
settings.severity.enable(Severity::warning);
if (portability)
settings.severity.enable(Severity::portability);
settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings.platform.defaultSign = 's'; settings.platform.defaultSign = 's';
Preprocessor preprocessor(settings); Preprocessor preprocessor(settings);
@ -2049,8 +2044,7 @@ private:
"[test.cpp:18]: (performance) Function parameter 'v' should be passed by const reference.\n", "[test.cpp:18]: (performance) Function parameter 'v' should be passed by const reference.\n",
errout.str()); errout.str());
Settings settings1; Settings settings1 = settingsBuilder().platform(cppcheck::Platform::Type::Win64).build();
PLATFORM(settings1.platform, cppcheck::Platform::Type::Win64);
check("using ui64 = unsigned __int64;\n" check("using ui64 = unsigned __int64;\n"
"ui64 Test(ui64 one, ui64 two) { return one + two; }\n", "ui64 Test(ui64 one, ui64 two) { return one + two; }\n",
/*filename*/ nullptr, /*inconclusive*/ true, /*runSimpleChecks*/ true, /*verbose*/ false, &settings1); /*filename*/ nullptr, /*inconclusive*/ true, /*runSimpleChecks*/ true, /*verbose*/ false, &settings1);
@ -2195,13 +2189,11 @@ private:
"};\n" "};\n"
"void f(X x) {}"; "void f(X x) {}";
Settings s32(_settings); Settings s32 = settingsBuilder(_settings).platform(cppcheck::Platform::Type::Unix32).build();
PLATFORM(s32.platform, cppcheck::Platform::Type::Unix32);
check(code, &s32); check(code, &s32);
ASSERT_EQUALS("[test.cpp:5]: (performance) Function parameter 'x' should be passed by const reference.\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (performance) Function parameter 'x' should be passed by const reference.\n", errout.str());
Settings s64(_settings); Settings s64 = settingsBuilder(_settings).platform(cppcheck::Platform::Type::Unix64).build();
PLATFORM(s64.platform, cppcheck::Platform::Type::Unix64);
check(code, &s64); check(code, &s64);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -7573,11 +7565,10 @@ private:
} }
{ {
Settings keepTemplates; Settings s = settingsBuilder().checkUnusedTemplates().build();
keepTemplates.checkUnusedTemplates = true;
check("template<int n> void foo(unsigned int x) {\n" check("template<int n> void foo(unsigned int x) {\n"
"if (x <= 0);\n" "if (x <= 0);\n"
"}", &keepTemplates); "}", &s);
ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned expression 'x' is less than zero.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned expression 'x' is less than zero.\n", errout.str());
} }
@ -7592,8 +7583,7 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (style) Checking if unsigned expression 'value' is less than zero.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (style) Checking if unsigned expression 'value' is less than zero.\n", errout.str());
// #9040 // #9040
Settings settings1; Settings settings1 = settingsBuilder().platform(cppcheck::Platform::Type::Win64).build();
PLATFORM(settings1.platform, cppcheck::Platform::Type::Win64);
check("using BOOL = unsigned;\n" check("using BOOL = unsigned;\n"
"int i;\n" "int i;\n"
"bool f() {\n" "bool f() {\n"
@ -10385,14 +10375,13 @@ private:
} }
void forwardAndUsed() { void forwardAndUsed() {
Settings keepTemplates; Settings s = settingsBuilder().checkUnusedTemplates().build();
keepTemplates.checkUnusedTemplates = true;
check("template<typename T>\n" check("template<typename T>\n"
"void f(T && t) {\n" "void f(T && t) {\n"
" g(std::forward<T>(t));\n" " g(std::forward<T>(t));\n"
" T s = t;\n" " T s = t;\n"
"}", &keepTemplates); "}", &s);
ASSERT_EQUALS("[test.cpp:4]: (warning) Access of forwarded variable 't'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (warning) Access of forwarded variable 't'.\n", errout.str());
} }

View File

@ -58,7 +58,7 @@ public:
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI(), &outputList); simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI(), &outputList);
if (errorLogger) { if (errorLogger) {
Settings settings; const Settings settings;
Preprocessor p(settings, errorLogger); Preprocessor p(settings, errorLogger);
p.reportOutput(outputList, true); p.reportOutput(outputList, true);
} }
@ -68,7 +68,7 @@ public:
}; };
private: private:
Settings settings0 = settingsBuilder().severity(Severity::information).build(); const Settings settings0 = settingsBuilder().severity(Severity::information).build();
Preprocessor preprocessor0{settings0, this}; Preprocessor preprocessor0{settings0, this};
void run() override { void run() override {
@ -468,9 +468,6 @@ private:
} }
void setPlatformInfo() { void setPlatformInfo() {
Settings settings;
Preprocessor preprocessor(settings, this);
// read code with simplecpp.. // read code with simplecpp..
const char filedata[] = "#if sizeof(long) == 4\n" const char filedata[] = "#if sizeof(long) == 4\n"
"1\n" "1\n"
@ -482,14 +479,20 @@ private:
simplecpp::TokenList tokens(istr, files, "test.c"); simplecpp::TokenList tokens(istr, files, "test.c");
// preprocess code with unix32 platform.. // preprocess code with unix32 platform..
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix32); {
preprocessor.setPlatformInfo(&tokens); const Settings settings = settingsBuilder().platform(cppcheck::Platform::Type::Unix32).build();
ASSERT_EQUALS("\n1", preprocessor.getcode(tokens, "", files, false)); Preprocessor preprocessor(settings, this);
preprocessor.setPlatformInfo(&tokens);
ASSERT_EQUALS("\n1", preprocessor.getcode(tokens, "", files, false));
}
// preprocess code with unix64 platform.. // preprocess code with unix64 platform..
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix64); {
preprocessor.setPlatformInfo(&tokens); const Settings settings = settingsBuilder().platform(cppcheck::Platform::Type::Unix64).build();
ASSERT_EQUALS("\n\n\n2", preprocessor.getcode(tokens, "", files, false)); Preprocessor preprocessor(settings, this);
preprocessor.setPlatformInfo(&tokens);
ASSERT_EQUALS("\n\n\n2", preprocessor.getcode(tokens, "", files, false));
}
} }
void includeguard1() { void includeguard1() {

View File

@ -39,7 +39,7 @@ public:
TestProcessExecutor() : TestFixture("TestProcessExecutor") {} TestProcessExecutor() : TestFixture("TestProcessExecutor") {}
private: private:
Settings settings; Settings settings = settingsBuilder().library("std.cfg").build();
/** /**
* Execute check using n jobs for y files which are have * Execute check using n jobs for y files which are have
@ -80,8 +80,6 @@ private:
void run() override { void run() override {
#if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) #if !defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
LOAD_LIB_2(settings.library, "std.cfg");
TEST_CASE(deadlock_with_many_errors); TEST_CASE(deadlock_with_many_errors);
TEST_CASE(many_threads); TEST_CASE(many_threads);
TEST_CASE(many_threads_showtime); TEST_CASE(many_threads_showtime);

View File

@ -309,8 +309,7 @@ private:
std::string tok_(const char* file, int line, const char code[], bool debugwarnings = false, cppcheck::Platform::Type type = cppcheck::Platform::Type::Native) { std::string tok_(const char* file, int line, const char code[], bool debugwarnings = false, cppcheck::Platform::Type type = cppcheck::Platform::Type::Native) {
errout.str(""); errout.str("");
Settings settings1 = settingsBuilder(settings).debugwarnings(debugwarnings).build(); const Settings settings1 = settingsBuilder(settings).debugwarnings(debugwarnings).platform(type).build();
PLATFORM(settings1.platform, type);
Tokenizer tokenizer(&settings1, this); Tokenizer tokenizer(&settings1, this);
std::istringstream istr(code); std::istringstream istr(code);

View File

@ -167,8 +167,7 @@ private:
std::string tok_(const char* file, int line, const char code[], bool simplify = true, cppcheck::Platform::Type type = cppcheck::Platform::Type::Native) { std::string tok_(const char* file, int line, const char code[], bool simplify = true, cppcheck::Platform::Type type = cppcheck::Platform::Type::Native) {
errout.str(""); errout.str("");
Settings settings = settings0; const Settings settings = settingsBuilder(settings0).platform(type).build();
PLATFORM(settings.platform, type);
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
@ -194,9 +193,7 @@ private:
std::string tokenizeAndStringify_(const char* file, int linenr, const char code[], bool simplify = false, bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", bool cpp11 = true) { std::string tokenizeAndStringify_(const char* file, int linenr, const char code[], bool simplify = false, bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", bool cpp11 = true) {
errout.str(""); errout.str("");
Settings settings = settingsBuilder(settings1).debugwarnings().build(); const Settings settings = settingsBuilder(settings1).debugwarnings().platform(platform).cpp(cpp11 ? Standards::CPP11 : Standards::CPP03).build();
PLATFORM(settings.platform, platform);
settings.standards.cpp = cpp11 ? Standards::CPP11 : Standards::CPP03;
// tokenize.. // tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);

View File

@ -228,8 +228,7 @@ private:
errout.str(""); errout.str("");
// show warnings about unhandled typedef // show warnings about unhandled typedef
Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings(debugwarnings).build(); const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings(debugwarnings).platform(type).build();
PLATFORM(settings.platform, type);
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);

View File

@ -100,8 +100,8 @@ private:
std::string tok_(const char* file, int line, const char code[], cppcheck::Platform::Type type = cppcheck::Platform::Type::Native, bool debugwarnings = true, bool preprocess = false) { std::string tok_(const char* file, int line, const char code[], cppcheck::Platform::Type type = cppcheck::Platform::Type::Native, bool debugwarnings = true, bool preprocess = false) {
errout.str(""); errout.str("");
Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings(debugwarnings).build(); const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings(debugwarnings).platform(type).build();
PLATFORM(settings.platform, type);
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
if (preprocess) { if (preprocess) {

View File

@ -41,7 +41,7 @@ public:
TestSingleExecutor() : TestFixture("TestSingleExecutor") {} TestSingleExecutor() : TestFixture("TestSingleExecutor") {}
private: private:
Settings settings; Settings settings = settingsBuilder().library("std.cfg").build();
static std::string zpad3(int i) static std::string zpad3(int i)
{ {
@ -89,8 +89,6 @@ private:
} }
void run() override { void run() override {
LOAD_LIB_2(settings.library, "std.cfg");
TEST_CASE(many_files); TEST_CASE(many_files);
TEST_CASE(many_files_showtime); TEST_CASE(many_files_showtime);
TEST_CASE(many_files_plist); TEST_CASE(many_files_plist);

View File

@ -70,7 +70,7 @@ private:
const Token* typetok{nullptr}; const Token* typetok{nullptr};
// If there are unused templates, keep those // If there are unused templates, keep those
Settings settings1 = settingsBuilder().library("std.cfg").checkUnusedTemplates().build(); Settings settings1 = settingsBuilder().library("std.cfg").checkUnusedTemplates().build();
Settings settings2 = settingsBuilder().checkUnusedTemplates().build(); const Settings settings2 = settingsBuilder().checkUnusedTemplates().platform(cppcheck::Platform::Type::Unspecified).build();
void reset() { void reset() {
vartok = nullptr; vartok = nullptr;
@ -115,8 +115,6 @@ private:
} }
void run() override { void run() override {
PLATFORM(settings2.platform, cppcheck::Platform::Type::Unspecified);
TEST_CASE(array); TEST_CASE(array);
TEST_CASE(array_ptr); TEST_CASE(array_ptr);
TEST_CASE(stlarray1); TEST_CASE(stlarray1);
@ -2040,6 +2038,7 @@ private:
} }
void functionDeclarations2() { void functionDeclarations2() {
const Settings settingsOld = settings1;
GET_SYMBOL_DB_STD("std::array<int,2> foo(int x);"); GET_SYMBOL_DB_STD("std::array<int,2> foo(int x);");
// 1 scopes: Global // 1 scopes: Global
@ -2058,9 +2057,12 @@ private:
const Token*parenthesis = foo->tokenDef->next(); const Token*parenthesis = foo->tokenDef->next();
ASSERT(parenthesis->str() == "(" && parenthesis->previous()->str() == "foo"); ASSERT(parenthesis->str() == "(" && parenthesis->previous()->str() == "foo");
ASSERT(parenthesis->valueType()->type == ValueType::Type::CONTAINER); ASSERT(parenthesis->valueType()->type == ValueType::Type::CONTAINER);
settings1 = settingsOld;
} }
void constexprFunction() { void constexprFunction() {
const Settings settingsOld = settings1;
GET_SYMBOL_DB_STD("constexpr int foo();"); GET_SYMBOL_DB_STD("constexpr int foo();");
// 1 scopes: Global // 1 scopes: Global
@ -2076,6 +2078,8 @@ private:
ASSERT(foo->tokenDef->str() == "foo"); ASSERT(foo->tokenDef->str() == "foo");
ASSERT(!foo->hasBody()); ASSERT(!foo->hasBody());
ASSERT(foo->isConstexpr()); ASSERT(foo->isConstexpr());
settings1 = settingsOld;
} }
void constructorInitialization() { void constructorInitialization() {
@ -4807,11 +4811,11 @@ private:
} }
void symboldatabase83() { // #9431 void symboldatabase83() { // #9431
const bool old = settings1.debugwarnings; const Settings settingsOld = settings1;
settings1.debugwarnings = true; settings1.debugwarnings = true;
GET_SYMBOL_DB("struct a { a() noexcept; };\n" GET_SYMBOL_DB("struct a { a() noexcept; };\n"
"a::a() noexcept = default;"); "a::a() noexcept = default;");
settings1.debugwarnings = old; settings1 = settingsOld;
const Scope *scope = db->findScopeByName("a"); const Scope *scope = db->findScopeByName("a");
ASSERT(scope); ASSERT(scope);
ASSERT(scope->functionList.size() == 1); ASSERT(scope->functionList.size() == 1);
@ -8043,8 +8047,7 @@ private:
} }
{ {
// PodType // PodType
Settings settingsWin64; Settings settingsWin64 = settingsBuilder().platform(cppcheck::Platform::Type::Win64).build();
settingsWin64.platform.type = cppcheck::Platform::Type::Win64;
const Library::PodType u32 = { 4, 'u' }; const Library::PodType u32 = { 4, 'u' };
const Library::PodType podtype2 = { 0, 'u', Library::PodType::Type::INT }; const Library::PodType podtype2 = { 0, 'u', Library::PodType::Type::INT };
settingsWin64.library.mPodTypes["u32"] = u32; settingsWin64.library.mPodTypes["u32"] = u32;
@ -8065,8 +8068,7 @@ private:
} }
{ {
// PlatformType // PlatformType
Settings settingsUnix32; Settings settingsUnix32 = settingsBuilder().platform(cppcheck::Platform::Type::Unix32).build();
settingsUnix32.platform.type = cppcheck::Platform::Type::Unix32;
Library::PlatformType s32; Library::PlatformType s32;
s32.mType = "int"; s32.mType = "int";
settingsUnix32.library.mPlatforms[settingsUnix32.platform.toString()].mPlatformTypes["s32"] = s32; settingsUnix32.library.mPlatforms[settingsUnix32.platform.toString()].mPlatformTypes["s32"] = s32;
@ -8076,8 +8078,7 @@ private:
} }
{ {
// PlatformType - wchar_t // PlatformType - wchar_t
Settings settingsWin64; Settings settingsWin64 = settingsBuilder().platform(cppcheck::Platform::Type::Win64).build();
settingsWin64.platform.type = cppcheck::Platform::Type::Win64;
Library::PlatformType lpctstr; Library::PlatformType lpctstr;
lpctstr.mType = "wchar_t"; lpctstr.mType = "wchar_t";
settingsWin64.library.mPlatforms[settingsWin64.platform.toString()].mPlatformTypes["LPCTSTR"] = lpctstr; settingsWin64.library.mPlatforms[settingsWin64.platform.toString()].mPlatformTypes["LPCTSTR"] = lpctstr;

View File

@ -45,7 +45,7 @@ public:
private: private:
// If there are unused templates, keep those // If there are unused templates, keep those
Settings settings0 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build(); const Settings settings0 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
const Settings settings1 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build(); const Settings settings1 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
const Settings settings2 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build(); const Settings settings2 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
const Settings settings_windows = settingsBuilder().library("windows.cfg").checkUnusedTemplates().build(); const Settings settings_windows = settingsBuilder().library("windows.cfg").checkUnusedTemplates().build();
@ -456,8 +456,7 @@ private:
std::string tokenizeAndStringify_(const char* file, int linenr, const char code[], bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", Standards::cppstd_t std = Standards::CPP11) { std::string tokenizeAndStringify_(const char* file, int linenr, const char code[], bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", Standards::cppstd_t std = Standards::CPP11) {
errout.str(""); errout.str("");
Settings settings = settingsBuilder(settings1).debugwarnings().cpp(std).build(); const Settings settings = settingsBuilder(settings1).debugwarnings().cpp(std).platform(platform).build();
PLATFORM(settings.platform, platform);
// tokenize.. // tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -484,8 +483,7 @@ private:
std::string tokenizeAndStringifyWindows_(const char* file, int linenr, const char code[], bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", bool cpp11 = true) { std::string tokenizeAndStringifyWindows_(const char* file, int linenr, const char code[], bool expand = true, cppcheck::Platform::Type platform = cppcheck::Platform::Type::Native, const char* filename = "test.cpp", bool cpp11 = true) {
errout.str(""); errout.str("");
Settings settings = settingsBuilder(settings_windows).debugwarnings().cpp(cpp11 ? Standards::CPP11 : Standards::CPP03).build(); const Settings settings = settingsBuilder(settings_windows).debugwarnings().cpp(cpp11 ? Standards::CPP11 : Standards::CPP03).platform(platform).build();
PLATFORM(settings.platform, platform);
// tokenize.. // tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -869,17 +867,15 @@ private:
void removePragma() { void removePragma() {
const char code[] = "_Pragma(\"abc\") int x;"; const char code[] = "_Pragma(\"abc\") int x;";
Settings s; const Settings s_c89 = settingsBuilder().c(Standards::C89).build();
ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s_c89, "test.c"));
const Settings s_clatest = settingsBuilder().c(Standards::CLatest).build();
ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s_clatest, "test.c"));
s.standards.c = Standards::C89; const Settings s_cpp03 = settingsBuilder().cpp(Standards::CPP03).build();
ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s, "test.c")); ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s_cpp03, "test.cpp"));
s.standards.c = Standards::CLatest; const Settings s_cpplatest = settingsBuilder().cpp(Standards::CPPLatest).build();
ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s, "test.c")); ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s_cpplatest, "test.cpp"));
s.standards.cpp = Standards::CPP03;
ASSERT_EQUALS("_Pragma ( \"abc\" ) int x ;", tokenizeAndStringify(code, s, "test.cpp"));
s.standards.cpp = Standards::CPPLatest;
ASSERT_EQUALS("int x ;", tokenizeAndStringify(code, s, "test.cpp"));
} }
void foreach () { void foreach () {
@ -921,8 +917,7 @@ private:
void simplifyHeadersAndUnusedTemplates1() { void simplifyHeadersAndUnusedTemplates1() {
Settings s; const Settings s = settingsBuilder().checkUnusedTemplates(false).build();
s.checkUnusedTemplates = false;
ASSERT_EQUALS(";", ASSERT_EQUALS(";",
tokenizeAndStringify("; template <typename... a> uint8_t b(std::tuple<uint8_t> d) {\n" tokenizeAndStringify("; template <typename... a> uint8_t b(std::tuple<uint8_t> d) {\n"
" std::tuple<a...> c{std::move(d)};\n" " std::tuple<a...> c{std::move(d)};\n"
@ -945,18 +940,21 @@ private:
" }\n" " }\n"
"};"; "};";
Settings s; {
s.checkUnusedTemplates = false; const Settings s = settingsBuilder().checkUnusedTemplates(false).build();
ASSERT_EQUALS(";", tokenizeAndStringify(code, s)); ASSERT_EQUALS(";", tokenizeAndStringify(code, s));
}
s.checkUnusedTemplates = true; {
ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n" const Settings s = settingsBuilder().checkUnusedTemplates().build();
"class Foo {\n" ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n"
"public:\n" "class Foo {\n"
"void FooBar ( ) {\n" "public:\n"
"new ( uBAR ? uBAR : sizeof ( T ) ) T ;\n" "void FooBar ( ) {\n"
"}\n" "new ( uBAR ? uBAR : sizeof ( T ) ) T ;\n"
"} ;", tokenizeAndStringify(code, s)); "}\n"
"} ;", tokenizeAndStringify(code, s));
}
} }
void simplifyAt() { void simplifyAt() {
@ -5194,8 +5192,7 @@ private:
} }
void simplifyOperatorName29() { void simplifyOperatorName29() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
ASSERT_EQUALS("auto operator<=> ( ) ;", tokenizeAndStringify("auto operator<=>();", settings)); ASSERT_EQUALS("auto operator<=> ( ) ;", tokenizeAndStringify("auto operator<=>();", settings));
} }
@ -5775,7 +5772,7 @@ private:
Z3 Z3
}; };
std::string testAst(const char code[], AstStyle style = AstStyle::Simple) { std::string testAst(const char code[], AstStyle style = AstStyle::Simple) const {
// tokenize given code.. // tokenize given code..
Tokenizer tokenList(&settings0, nullptr); Tokenizer tokenList(&settings0, nullptr);
std::istringstream istr(code); std::istringstream istr(code);
@ -5824,7 +5821,7 @@ private:
return ret; return ret;
} }
void astexpr() { // simple expressions with arithmetical ops void astexpr() const { // simple expressions with arithmetical ops
ASSERT_EQUALS("12+3+", testAst("1+2+3")); ASSERT_EQUALS("12+3+", testAst("1+2+3"));
ASSERT_EQUALS("12*3+", testAst("1*2+3")); ASSERT_EQUALS("12*3+", testAst("1*2+3"));
ASSERT_EQUALS("123*+", testAst("1+2*3")); ASSERT_EQUALS("123*+", testAst("1+2*3"));
@ -6084,7 +6081,7 @@ private:
ASSERT_NO_THROW(tokenizeAndStringify(code)); ASSERT_NO_THROW(tokenizeAndStringify(code));
} }
void astnewdelete() { void astnewdelete() const {
ASSERT_EQUALS("aintnew=", testAst("a = new int;")); ASSERT_EQUALS("aintnew=", testAst("a = new int;"));
ASSERT_EQUALS("aint4[new=", testAst("a = new int[4];")); ASSERT_EQUALS("aint4[new=", testAst("a = new int[4];"));
ASSERT_EQUALS("aFoobar(new=", testAst("a = new Foo(bar);")); ASSERT_EQUALS("aFoobar(new=", testAst("a = new Foo(bar);"));
@ -6301,7 +6298,7 @@ private:
"}\n")); "}\n"));
} }
void astbrackets() { // [] void astbrackets() const { // []
ASSERT_EQUALS("a23+[4+", testAst("a[2+3]+4")); ASSERT_EQUALS("a23+[4+", testAst("a[2+3]+4"));
ASSERT_EQUALS("a1[0[", testAst("a[1][0]")); ASSERT_EQUALS("a1[0[", testAst("a[1][0]"));
ASSERT_EQUALS("ab0[=", testAst("a=(b)[0];")); ASSERT_EQUALS("ab0[=", testAst("a=(b)[0];"));
@ -6309,7 +6306,7 @@ private:
ASSERT_EQUALS("ab0[1[=", testAst("a=b[0][1];")); ASSERT_EQUALS("ab0[1[=", testAst("a=b[0][1];"));
} }
void astvardecl() { void astvardecl() const {
// Variable declaration // Variable declaration
ASSERT_EQUALS("a1[\"\"=", testAst("char a[1]=\"\";")); ASSERT_EQUALS("a1[\"\"=", testAst("char a[1]=\"\";"));
ASSERT_EQUALS("charp*(3[char5[3[new=", testAst("char (*p)[3] = new char[5][3];")); ASSERT_EQUALS("charp*(3[char5[3[new=", testAst("char (*p)[3] = new char[5][3];"));
@ -6343,7 +6340,7 @@ private:
ASSERT_EQUALS("i(j=", testAst("(int&)(i) = j;")); ASSERT_EQUALS("i(j=", testAst("(int&)(i) = j;"));
} }
void astunaryop() { // unary operators void astunaryop() const { // unary operators
ASSERT_EQUALS("1a--+", testAst("1 + --a")); ASSERT_EQUALS("1a--+", testAst("1 + --a"));
ASSERT_EQUALS("1a--+", testAst("1 + a--")); ASSERT_EQUALS("1a--+", testAst("1 + a--"));
ASSERT_EQUALS("ab+!", testAst("!(a+b)")); ASSERT_EQUALS("ab+!", testAst("!(a+b)"));
@ -6369,7 +6366,7 @@ private:
ASSERT_EQUALS("int0{1&return", testAst("int g() { return int{ 0 } & 1; }")); ASSERT_EQUALS("int0{1&return", testAst("int g() { return int{ 0 } & 1; }"));
} }
void astfunction() { // function calls void astfunction() const { // function calls
ASSERT_EQUALS("1f(+2+", testAst("1+f()+2")); ASSERT_EQUALS("1f(+2+", testAst("1+f()+2"));
ASSERT_EQUALS("1f2(+3+", testAst("1+f(2)+3")); ASSERT_EQUALS("1f2(+3+", testAst("1+f(2)+3"));
ASSERT_EQUALS("1f23,(+4+", testAst("1+f(2,3)+4")); ASSERT_EQUALS("1f23,(+4+", testAst("1+f(2,3)+4"));
@ -6414,7 +6411,7 @@ private:
"}\n")); "}\n"));
} }
void astcast() { void astcast() const {
ASSERT_EQUALS("ac&(=", testAst("a = (long)&c;")); ASSERT_EQUALS("ac&(=", testAst("a = (long)&c;"));
ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;")); ASSERT_EQUALS("ac*(=", testAst("a = (Foo*)*c;"));
ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;")); ASSERT_EQUALS("ac-(=", testAst("a = (long)-c;"));
@ -6587,14 +6584,14 @@ private:
ASSERT_EQUALS("sf.{(i[{={", testAst("void g(int i) { S s{ .f = { [i]() {} } }; }")); ASSERT_EQUALS("sf.{(i[{={", testAst("void g(int i) { S s{ .f = { [i]() {} } }; }"));
} }
void astcase() { void astcase() const {
ASSERT_EQUALS("0case", testAst("case 0:")); ASSERT_EQUALS("0case", testAst("case 0:"));
ASSERT_EQUALS("12+case", testAst("case 1+2:")); ASSERT_EQUALS("12+case", testAst("case 1+2:"));
ASSERT_EQUALS("xyz:?case", testAst("case (x?y:z):")); ASSERT_EQUALS("xyz:?case", testAst("case (x?y:z):"));
ASSERT_EQUALS("switchx( 1case y++ 2case", testAst("switch(x){case 1:{++y;break;case 2:break;}}")); ASSERT_EQUALS("switchx( 1case y++ 2case", testAst("switch(x){case 1:{++y;break;case 2:break;}}"));
} }
void astrefqualifier() { void astrefqualifier() const {
ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&; };")); ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&; };"));
ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&&; };")); ASSERT_EQUALS("b(int.", testAst("class a { auto b() -> int&&; };"));
ASSERT_EQUALS("b(", testAst("class a { void b() &&; };")); ASSERT_EQUALS("b(", testAst("class a { void b() &&; };"));
@ -6605,7 +6602,7 @@ private:
//Verify that returning a newly constructed object generates the correct AST even when the class name is scoped //Verify that returning a newly constructed object generates the correct AST even when the class name is scoped
//Addresses https://trac.cppcheck.net/ticket/9700 //Addresses https://trac.cppcheck.net/ticket/9700
void astnewscoped() { void astnewscoped() const {
ASSERT_EQUALS("(return (new A))", testAst("return new A;", AstStyle::Z3)); ASSERT_EQUALS("(return (new A))", testAst("return new A;", AstStyle::Z3));
ASSERT_EQUALS("(return (new (( A)))", testAst("return new A();", AstStyle::Z3)); ASSERT_EQUALS("(return (new (( A)))", testAst("return new A();", AstStyle::Z3));
ASSERT_EQUALS("(return (new (( A true)))", testAst("return new A(true);", AstStyle::Z3)); ASSERT_EQUALS("(return (new (( A true)))", testAst("return new A(true);", AstStyle::Z3));
@ -7315,8 +7312,7 @@ private:
void checkConfig(const char code[]) { void checkConfig(const char code[]) {
errout.str(""); errout.str("");
Settings s; const Settings s = settingsBuilder().checkConfiguration().build();
s.checkConfiguration = true;
// tokenize.. // tokenize..
Tokenizer tokenizer(&s, this); Tokenizer tokenizer(&s, this);
@ -7332,8 +7328,7 @@ private:
void unknownType() { // #8952 void unknownType() { // #8952
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Settings settings; const Settings settings = settingsBuilder().debugwarnings().build();
settings.debugwarnings = true;
char code[] = "class A {\n" char code[] = "class A {\n"
"public:\n" "public:\n"
@ -7362,7 +7357,7 @@ private:
"a = reinterpret_cast<int>(x);\n" "a = reinterpret_cast<int>(x);\n"
"a = static_cast<int>(x);\n"; "a = static_cast<int>(x);\n";
Settings settings; const Settings settings;
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp")); ASSERT(tokenizer.tokenize(istr, "test.cpp"));
@ -7376,8 +7371,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings; const Settings settings = settingsBuilder().checkHeaders(checkHeadersFlag).build();
settings.checkHeaders = checkHeadersFlag;
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");
@ -7449,8 +7443,7 @@ private:
} }
void simplifyCoroutines() { void simplifyCoroutines() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
const char code1[] = "generator<int> f() { co_yield start++; }"; const char code1[] = "generator<int> f() { co_yield start++; }";
const char expected1[] = "generator < int > f ( ) { co_yield ( start ++ ) ; }"; const char expected1[] = "generator < int > f ( ) { co_yield ( start ++ ) ; }";
@ -7466,60 +7459,53 @@ private:
} }
void simplifySpaceshipOperator() { void simplifySpaceshipOperator() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
ASSERT_EQUALS("; x <=> y ;", tokenizeAndStringify(";x<=>y;", settings)); ASSERT_EQUALS("; x <=> y ;", tokenizeAndStringify(";x<=>y;", settings));
} }
void simplifyIfSwitchForInit1() { void simplifyIfSwitchForInit1() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP17).build();
settings.standards.cpp = Standards::CPP17;
const char code[] = "void f() { if (a;b) {} }"; const char code[] = "void f() { if (a;b) {} }";
ASSERT_EQUALS("void f ( ) { { a ; if ( b ) { } } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { { a ; if ( b ) { } } }", tokenizeAndStringify(code, settings));
} }
void simplifyIfSwitchForInit2() { void simplifyIfSwitchForInit2() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
const char code[] = "void f() { if (a;b) {} else {} }"; const char code[] = "void f() { if (a;b) {} else {} }";
ASSERT_EQUALS("void f ( ) { { a ; if ( b ) { } else { } } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { { a ; if ( b ) { } else { } } }", tokenizeAndStringify(code, settings));
} }
void simplifyIfSwitchForInit3() { void simplifyIfSwitchForInit3() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
const char code[] = "void f() { switch (a;b) {} }"; const char code[] = "void f() { switch (a;b) {} }";
ASSERT_EQUALS("void f ( ) { { a ; switch ( b ) { } } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { { a ; switch ( b ) { } } }", tokenizeAndStringify(code, settings));
} }
void simplifyIfSwitchForInit4() { void simplifyIfSwitchForInit4() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
const char code[] = "void f() { for (a;b:c) {} }"; const char code[] = "void f() { for (a;b:c) {} }";
ASSERT_EQUALS("void f ( ) { { a ; for ( b : c ) { } } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { { a ; for ( b : c ) { } } }", tokenizeAndStringify(code, settings));
} }
void simplifyIfSwitchForInit5() { void simplifyIfSwitchForInit5() {
Settings settings; const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();
settings.standards.cpp = Standards::CPP20;
const char code[] = "void f() { if ([] { ; }) {} }"; const char code[] = "void f() { if ([] { ; }) {} }";
ASSERT_EQUALS("void f ( ) { if ( [ ] { ; } ) { } }", tokenizeAndStringify(code, settings)); ASSERT_EQUALS("void f ( ) { if ( [ ] { ; } ) { } }", tokenizeAndStringify(code, settings));
} }
void cpp20_default_bitfield_initializer() { void cpp20_default_bitfield_initializer() {
Settings settings; const Settings s1 = settingsBuilder().cpp(Standards::CPP20).build();
const char code[] = "struct S { int a:2 = 0; };"; const char code[] = "struct S { int a:2 = 0; };";
settings.standards.cpp = Standards::CPP20; ASSERT_EQUALS("struct S { int a ; a = 0 ; } ;", tokenizeAndStringify(code, s1));
ASSERT_EQUALS("struct S { int a ; a = 0 ; } ;", tokenizeAndStringify(code, settings)); const Settings s2 = settingsBuilder().cpp(Standards::CPP17).build();
settings.standards.cpp = Standards::CPP17; ASSERT_THROW(tokenizeAndStringify(code, s2), InternalError);
ASSERT_THROW(tokenizeAndStringify(code, settings), InternalError);
} }
void cpp11init() { void cpp11init() {
#define testIsCpp11init(...) testIsCpp11init_(__FILE__, __LINE__, __VA_ARGS__) #define testIsCpp11init(...) testIsCpp11init_(__FILE__, __LINE__, __VA_ARGS__)
auto testIsCpp11init_ = [this](const char* file, int line, const char* code, const char* find, TokenImpl::Cpp11init expected) { auto testIsCpp11init_ = [this](const char* file, int line, const char* code, const char* find, TokenImpl::Cpp11init expected) {
Settings settings; const Settings settings;
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

@ -45,40 +45,37 @@ 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, const char filename[] = "test.cpp", const std::string& standard = "c++11") { void check_(const char* file, int line, const char code[], const Settings& settings, const char filename[] = "test.cpp", Standards::cppstd_t standard = Standards::cppstd_t::CPP11) {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings->severity.enable(Severity::warning); const Settings settings1 = settingsBuilder(settings).severity(Severity::warning).severity(Severity::portability).cpp(standard).build();
settings->severity.enable(Severity::portability);
settings->standards.setCPP(standard);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(settings, this); Tokenizer tokenizer(&settings1, this);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line);
// Check.. // Check..
runChecks<CheckType>(&tokenizer, settings, this); runChecks<CheckType>(&tokenizer, &settings1, this);
} }
void checkTooBigShift_Unix32() { void checkTooBigShift_Unix32() {
Settings settings0; const Settings settings0;
Settings settings; const Settings settings = settingsBuilder().platform(cppcheck::Platform::Type::Unix32).build();
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix32);
// unsigned types getting promoted to int sizeof(int) = 4 bytes // unsigned types getting promoted to int sizeof(int) = 4 bytes
// and unsigned types having already a size of 4 bytes // and unsigned types having already a size of 4 bytes
{ {
const std::string types[] = {"unsigned char", /*[unsigned]*/ "char", "bool", "unsigned short", "unsigned int", "unsigned long"}; const std::string types[] = {"unsigned char", /*[unsigned]*/ "char", "bool", "unsigned short", "unsigned int", "unsigned long"};
for (const std::string& type : types) { for (const std::string& type : types) {
check((type + " f(" + type +" x) { return x << 31; }").c_str(), &settings); check((type + " f(" + type +" x) { return x << 31; }").c_str(), settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check((type + " f(" + type +" x) { return x << 33; }").c_str(), &settings); check((type + " f(" + type +" x) { return x << 33; }").c_str(), settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str());
check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), &settings); check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str());
check((type + " foo(" + type + " x) { return x << 31; }").c_str(), &settings); check((type + " foo(" + type + " x) { return x << 31; }").c_str(), settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
} }
@ -88,68 +85,68 @@ private:
const std::string types[] = {"signed char", "signed short", /*[signed]*/ "short", "wchar_t", /*[signed]*/ "int", "signed int", /*[signed]*/ "long", "signed long"}; const std::string types[] = {"signed char", "signed short", /*[signed]*/ "short", "wchar_t", /*[signed]*/ "int", "signed int", /*[signed]*/ "long", "signed long"};
for (const std::string& type : types) { for (const std::string& type : types) {
// c++11 // c++11
check((type + " f(" + type +" x) { return x << 33; }").c_str(), &settings); check((type + " f(" + type +" x) { return x << 33; }").c_str(), settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 33 bits is undefined behaviour\n", errout.str());
check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), &settings); check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str());
check((type + " foo(" + type + " x) { return x << 31; }").c_str(), &settings); check((type + " foo(" + type + " x) { return x << 31; }").c_str(), settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour\n", errout.str());
check((type + " foo(" + type + " x) { return x << 30; }").c_str(), &settings); check((type + " foo(" + type + " x) { return x << 30; }").c_str(), settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// c++14 // c++14
check((type + " foo(" + type + " x) { return x << 31; }").c_str(), &settings, "test.cpp", "c++14"); check((type + " foo(" + type + " x) { return x << 31; }").c_str(), settings, "test.cpp", Standards::cppstd_t::CPP14);
ASSERT_EQUALS("[test.cpp:1]: (portability) Shifting signed 32-bit value by 31 bits is implementation-defined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (portability) Shifting signed 32-bit value by 31 bits is implementation-defined behaviour\n", errout.str());
check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), &settings, "test.cpp", "c++14"); check((type + " f(int x) { return (x = (" + type + ")x << 32); }").c_str(), settings, "test.cpp", Standards::cppstd_t::CPP14);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str());
} }
} }
// 64 bit width types // 64 bit width types
{ {
// unsigned long long // unsigned long long
check("unsigned long long foo(unsigned long long x) { return x << 64; }",&settings); check("unsigned long long foo(unsigned long long x) { return x << 64; }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("unsigned long long f(int x) { return (x = (unsigned long long)x << 64); }",&settings); check("unsigned long long f(int x) { return (x = (unsigned long long)x << 64); }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("unsigned long long f(unsigned long long x) { return x << 63; }",&settings); check("unsigned long long f(unsigned long long x) { return x << 63; }",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// [signed] long long // [signed] long long
check("long long foo(long long x) { return x << 64; }",&settings); check("long long foo(long long x) { return x << 64; }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("long long f(int x) { return (x = (long long)x << 64); }",&settings); check("long long f(int x) { return (x = (long long)x << 64); }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("long long f(long long x) { return x << 63; }",&settings); check("long long f(long long x) { return x << 63; }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 64-bit value by 63 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 64-bit value by 63 bits is undefined behaviour\n", errout.str());
check("long long f(long long x) { return x << 62; }",&settings); check("long long f(long long x) { return x << 62; }",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// signed long long // signed long long
check("signed long long foo(signed long long x) { return x << 64; }",&settings); check("signed long long foo(signed long long x) { return x << 64; }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("signed long long f(long long x) { return (x = (signed long long)x << 64); }",&settings); check("signed long long f(long long x) { return (x = (signed long long)x << 64); }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("signed long long f(signed long long x) { return x << 63; }",&settings); check("signed long long f(signed long long x) { return x << 63; }",settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 64-bit value by 63 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting signed 64-bit value by 63 bits is undefined behaviour\n", errout.str());
check("signed long long f(signed long long x) { return x << 62; }",&settings); check("signed long long f(signed long long x) { return x << 62; }",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// c++14 // c++14
check("signed long long foo(signed long long x) { return x << 64; }",&settings, "test.cpp", "c++14"); check("signed long long foo(signed long long x) { return x << 64; }",settings, "test.cpp", Standards::cppstd_t::CPP14);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("signed long long f(long long x) { return (x = (signed long long)x << 64); }",&settings, "test.cpp", "c++14"); check("signed long long f(long long x) { return (x = (signed long long)x << 64); }",settings, "test.cpp", Standards::cppstd_t::CPP14);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 64-bit value by 64 bits is undefined behaviour\n", errout.str());
check("signed long long f(signed long long x) { return x << 63; }",&settings, "test.cpp", "c++14"); check("signed long long f(signed long long x) { return x << 63; }",settings, "test.cpp", Standards::cppstd_t::CPP14);
ASSERT_EQUALS("[test.cpp:1]: (portability) Shifting signed 64-bit value by 63 bits is implementation-defined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (portability) Shifting signed 64-bit value by 63 bits is implementation-defined behaviour\n", errout.str());
check("signed long long f(signed long long x) { return x << 62; }",&settings); check("signed long long f(signed long long x) { return x << 62; }",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
check("void f() { int x; x = 1 >> 64; }", &settings); check("void f() { int x; x = 1 >> 64; }", settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 64 bits is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 32-bit value by 64 bits is undefined behaviour\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" QList<int> someList;\n" " QList<int> someList;\n"
" someList << 300;\n" " someList << 300;\n"
"}", &settings); "}", settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// Ticket #6793 // Ticket #6793
@ -157,14 +154,14 @@ private:
"const unsigned int f = foo<31>(0);\n" "const unsigned int f = foo<31>(0);\n"
"const unsigned int g = foo<100>(0);\n" "const unsigned int g = foo<100>(0);\n"
"template<unsigned int I> int hoo(unsigned int x) { return x << 32; }\n" "template<unsigned int I> int hoo(unsigned int x) { return x << 32; }\n"
"const unsigned int h = hoo<100>(0);", &settings); "const unsigned int h = hoo<100>(0);", settings);
ASSERT_EQUALS("[test.cpp:4]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n" ASSERT_EQUALS("[test.cpp:4]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n"
"[test.cpp:1]: (error) Shifting 32-bit value by 100 bits is undefined behaviour\n", errout.str()); "[test.cpp:1]: (error) Shifting 32-bit value by 100 bits is undefined behaviour\n", errout.str());
// #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); "}", settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #8640 // #8640
@ -174,7 +171,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); "}", 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());
@ -185,7 +182,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); "}", 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());
@ -197,7 +194,7 @@ private:
" return 0;\n" " return 0;\n"
" else\n" " else\n"
" return rm>> k;\n" " return rm>> k;\n"
"}", &settings0); "}", 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());
@ -209,20 +206,20 @@ private:
" return 0;\n" " return 0;\n"
" else\n" " else\n"
" return rm>> k;\n" " return rm>> k;\n"
"}", &settings0); "}", 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); "}", 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); "}", 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
@ -233,71 +230,69 @@ private:
" if (bits == 512)\n" " if (bits == 512)\n"
" len -= 8;\n" " len -= 8;\n"
" }\n" " }\n"
"}\n", &settings0); "}\n", settings0);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void checkIntegerOverflow() { void checkIntegerOverflow() {
Settings settings = settingsBuilder().severity(Severity::warning).build(); const Settings settings = settingsBuilder().severity(Severity::warning).platform(cppcheck::Platform::Type::Unix32).build();
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix32);
check("x = (int)0x10000 * (int)0x10000;", &settings); check("x = (int)0x10000 * (int)0x10000;", settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(int)0x10000*(int)0x10000'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(int)0x10000*(int)0x10000'.\n", errout.str());
check("x = (long)0x10000 * (long)0x10000;", &settings); check("x = (long)0x10000 * (long)0x10000;", settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(long)0x10000*(long)0x10000'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(long)0x10000*(long)0x10000'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" int intmax = 0x7fffffff;\n" " int intmax = 0x7fffffff;\n"
" return intmax + 1;\n" " return intmax + 1;\n"
"}",&settings); "}",settings);
ASSERT_EQUALS("[test.cpp:3]: (error) Signed integer overflow for expression 'intmax+1'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Signed integer overflow for expression 'intmax+1'.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" int intmax = 0x7fffffff;\n" " int intmax = 0x7fffffff;\n"
" return intmax - 1;\n" " return intmax - 1;\n"
"}",&settings); "}",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int foo(signed int x) {\n" check("int foo(signed int x) {\n"
" if (x==123456) {}\n" " if (x==123456) {}\n"
" return x * x;\n" " return x * x;\n"
"}",&settings); "}",settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression 'x*x'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression 'x*x'.\n", errout.str());
check("int foo(signed int x) {\n" check("int foo(signed int x) {\n"
" if (x==123456) {}\n" " if (x==123456) {}\n"
" return -123456 * x;\n" " return -123456 * x;\n"
"}",&settings); "}",settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression '-123456*x'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==123456' is redundant or there is signed integer overflow for expression '-123456*x'.\n", errout.str());
check("int foo(signed int x) {\n" check("int foo(signed int x) {\n"
" if (x==123456) {}\n" " if (x==123456) {}\n"
" return 123456U * x;\n" " return 123456U * x;\n"
"}",&settings); "}",settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void signConversion() { void signConversion() {
Settings settings0; const Settings settings0;
Settings settings; const Settings settings = settingsBuilder().platform(cppcheck::Platform::Type::Unix64).build();
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix64); check("x = -4 * (unsigned)y;", settings0);
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;", &settings0); 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
" if (x==0) {}\n" " if (x==0) {}\n"
" return (x-1)*sizeof(int);\n" " return (x-1)*sizeof(int);\n"
"}", &settings); "}", settings);
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Expression 'x-1' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Expression 'x-1' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout.str());
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); }", &settings0); "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());
@ -305,7 +300,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); }", &settings0); "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());
@ -313,65 +308,64 @@ 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); }", &settings0); "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); }", &settings0); "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); "}", 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());
} }
void longCastAssign() { void longCastAssign() {
Settings settings = settingsBuilder().severity(Severity::style).build(); const Settings settings = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build();
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix64);
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
" const long ret = x * y;\n" " const long ret = x * y;\n"
" return ret;\n" " return ret;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n", errout.str());
check("long f() {\n" check("long f() {\n"
" const long long ret = 256 * (1 << 10);\n" " const long long ret = 256 * (1 << 10);\n"
" return ret;\n" " return ret;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// typedef // typedef
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
" const size_t ret = x * y;\n" " const size_t ret = x * y;\n"
" return ret;\n" " return ret;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// astIsIntResult // astIsIntResult
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
" const long ret = (long)x * y;\n" " const long ret = (long)x * y;\n"
" return ret;\n" " return ret;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void longCastReturn() { void longCastReturn() {
Settings settings = settingsBuilder().severity(Severity::style).build(); const Settings settings = settingsBuilder().severity(Severity::style).build();
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
" return x * y;\n" " return x * y;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long value. If the return value is long to avoid loss of information, then you have loss of information.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) int result is returned as long value. If the return value is long to avoid loss of information, then you have loss of information.\n", errout.str());
// typedef // typedef
check("size_t f(int x, int y) {\n" check("size_t f(int x, int y) {\n"
" return x * y;\n" " return x * y;\n"
"}\n", &settings); "}\n", settings);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -386,43 +380,43 @@ private:
} }
void checkFloatToIntegerOverflow() { void checkFloatToIntegerOverflow() {
Settings settings; const Settings settings;
check("x = (int)1E100;", &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); "}", 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); "}", 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); "}", 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); "}", 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); "}", 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); "}", 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); "}", 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

@ -119,8 +119,6 @@ private:
// Check for redundant code.. // Check for redundant code..
CheckUninitVar checkuninitvar(&tokenizer, &settings1, this); CheckUninitVar checkuninitvar(&tokenizer, &settings1, this);
checkuninitvar.check(); checkuninitvar.check();
settings.debugwarnings = false;
} }
void uninitvar1() { void uninitvar1() {
@ -832,6 +830,7 @@ private:
"}", "test.cpp", false); "}", "test.cpp", false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
const Settings settingsOld = settings;
// Ticket #6701 - Variable name is a POD type according to cfg // Ticket #6701 - Variable name is a POD type according to cfg
const char xmldata[] = "<?xml version=\"1.0\"?>\n" const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def format=\"1\">" "<def format=\"1\">"
@ -843,6 +842,7 @@ private:
" _tm.dostuff();\n" " _tm.dostuff();\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
settings = settingsOld;
// Ticket #7822 - Array type // Ticket #7822 - Array type
checkUninitVar("A *f() {\n" checkUninitVar("A *f() {\n"
@ -4349,6 +4349,7 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
{ {
const Settings settingsOld = settings;
const char argDirectionsTestXmlData[] = "<?xml version=\"1.0\"?>\n" const char argDirectionsTestXmlData[] = "<?xml version=\"1.0\"?>\n"
"<def>\n" "<def>\n"
" <function name=\"uninitvar_funcArgInTest\">\n" " <function name=\"uninitvar_funcArgInTest\">\n"
@ -4376,6 +4377,7 @@ private:
" x = ab;\n" " x = ab;\n"
"}\n", "test.c"); "}\n", "test.c");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
settings = settingsOld;
} }
checkUninitVar("struct AB { int a; int b; };\n" checkUninitVar("struct AB { int a; int b; };\n"
@ -5207,14 +5209,14 @@ private:
errout.str(""); errout.str("");
// Tokenize.. // Tokenize..
settings.debugwarnings = false; const Settings s = settingsBuilder(settings).debugwarnings(false).build();
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&s, this);
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, fname), file, line); ASSERT_LOC(tokenizer.tokenize(istr, fname), file, line);
// Check for redundant code.. // Check for redundant code..
CheckUninitVar checkuninitvar(&tokenizer, &settings, this); CheckUninitVar checkuninitvar(&tokenizer, &s, this);
(checkuninitvar.valueFlowUninit)(); (checkuninitvar.valueFlowUninit)();
} }

View File

@ -81,18 +81,18 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
PLATFORM(settings.platform, platform); const Settings settings1 = settingsBuilder(settings).platform(platform).build();
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings1, 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);
// Check for unused functions.. // Check for unused functions..
CheckUnusedFunctions checkUnusedFunctions(&tokenizer, &settings, this); CheckUnusedFunctions checkUnusedFunctions(&tokenizer, &settings1, this);
checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings); checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings1);
// check() returns error if and only if errout is not empty. // check() returns error if and only if errout is not empty.
if ((checkUnusedFunctions.check)(this, settings)) { if ((checkUnusedFunctions.check)(this, settings1)) {
ASSERT(!errout.str().empty()); ASSERT(!errout.str().empty());
} else { } else {
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
@ -612,7 +612,7 @@ private:
check("int _tmain() { }"); check("int _tmain() { }");
ASSERT_EQUALS("[test.cpp:1]: (style) The function '_tmain' is never used.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (style) The function '_tmain' is never used.\n", errout.str());
Settings settingsOld = settings; const Settings settingsOld = settings;
LOAD_LIB_2(settings.library, "windows.cfg"); LOAD_LIB_2(settings.library, "windows.cfg");
check("int WinMain() { }"); check("int WinMain() { }");
@ -631,7 +631,7 @@ private:
check("int _tmain() { }"); check("int _tmain() { }");
ASSERT_EQUALS("[test.cpp:1]: (style) The function '_tmain' is never used.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (style) The function '_tmain' is never used.\n", errout.str());
Settings settingsOld = settings; const Settings settingsOld = settings;
LOAD_LIB_2(settings.library, "windows.cfg"); LOAD_LIB_2(settings.library, "windows.cfg");
check("int wWinMain() { }"); check("int wWinMain() { }");
@ -649,7 +649,7 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (style) The function '_init' is never used.\n" ASSERT_EQUALS("[test.cpp:1]: (style) The function '_init' is never used.\n"
"[test.cpp:2]: (style) The function '_fini' is never used.\n", errout.str()); "[test.cpp:2]: (style) The function '_fini' is never used.\n", errout.str());
Settings settingsOld = settings; const Settings settingsOld = settings;
LOAD_LIB_2(settings.library, "gnu.cfg"); LOAD_LIB_2(settings.library, "gnu.cfg");
check("int _init() { }\n" check("int _init() { }\n"

View File

@ -36,7 +36,7 @@ public:
TestUnusedPrivateFunction() : TestFixture("TestUnusedPrivateFunction") {} TestUnusedPrivateFunction() : TestFixture("TestUnusedPrivateFunction") {}
private: private:
Settings settings = settingsBuilder().severity(Severity::style).build(); const Settings settings = settingsBuilder().severity(Severity::style).build();
void run() override { void run() override {
TEST_CASE(test1); TEST_CASE(test1);
@ -94,7 +94,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
PLATFORM(settings.platform, platform); const Settings settings1 = settingsBuilder(settings).platform(platform).build();
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");
@ -107,12 +107,12 @@ private:
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings1, this);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
// Check for unused private functions.. // Check for unused private functions..
CheckClass checkClass(&tokenizer, &settings, this); CheckClass checkClass(&tokenizer, &settings1, this);
checkClass.privateFunctions(); checkClass.privateFunctions();
} }

View File

@ -1787,6 +1787,7 @@ private:
ASSERT_EQUALS("[test.cpp:1]: (style) struct member 'A::i' is never used.\n", ASSERT_EQUALS("[test.cpp:1]: (style) struct member 'A::i' is never used.\n",
errout.str()); errout.str());
const Settings settingsOld = settings;
settings.enforcedLang = Settings::C; settings.enforcedLang = Settings::C;
checkStructMemberUsage("struct A {\n" // #10852 checkStructMemberUsage("struct A {\n" // #10852
" struct B {\n" " struct B {\n"
@ -1816,7 +1817,7 @@ private:
" pc->s[0] = 1;\n" " pc->s[0] = 1;\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
settings.enforcedLang = Settings::None; settings = settingsOld;
} }
void structmember20() { // #10737 void structmember20() { // #10737

View File

@ -485,7 +485,7 @@ private:
} }
void bailout(const char code[]) { void bailout(const char code[]) {
settings.debugwarnings = true; const Settings s = settingsBuilder().debugwarnings().build();
errout.str(""); errout.str("");
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");
@ -497,11 +497,9 @@ private:
simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI());
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&s, this);
tokenizer.createTokens(std::move(tokens2)); tokenizer.createTokens(std::move(tokens2));
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
settings.debugwarnings = false;
} }
#define tokenValues(...) tokenValues_(__FILE__, __LINE__, __VA_ARGS__) #define tokenValues(...) tokenValues_(__FILE__, __LINE__, __VA_ARGS__)

View File

@ -34,10 +34,8 @@ public:
TestVarID() : TestFixture("TestVarID") {} TestVarID() : TestFixture("TestVarID") {}
private: private:
Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).checkUnusedTemplates().build(); Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).checkUnusedTemplates().platform(cppcheck::Platform::Type::Unix64).build();
void run() override { void run() override {
PLATFORM(settings.platform, cppcheck::Platform::Type::Unix64);
TEST_CASE(varid1); TEST_CASE(varid1);
TEST_CASE(varid2); TEST_CASE(varid2);
TEST_CASE(varid3); TEST_CASE(varid3);
@ -2023,7 +2021,7 @@ private:
void varid_in_class25() { void varid_in_class25() {
const char *code{}, *expected{}; const char *code{}, *expected{};
Settings oldSettings = settings; const Settings oldSettings = settings;
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
code = "struct F {\n" // #11497 code = "struct F {\n" // #11497