diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 24bbaf9430a..e53f2a323b2 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -41,17 +41,18 @@ class TestBufferOverrun : public TestFixture { struct CheckOptions { - const Settings* s = nullptr; bool cpp = true; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings& settings = options.s ? *options.s : settings0_i; + check_(file, line, code, settings0_i, options.cpp); + } - // Tokenize.. - SimpleTokenizer tokenizer(settings, *this, options.cpp); + template + void check_(const char* file, int line, const char (&code)[size], const Settings& settings, bool cpp = true) { + SimpleTokenizer tokenizer(settings, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for buffer overruns.. @@ -3503,7 +3504,7 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char *p = malloc(10);\n" " memset(p, 0, 20);\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:3:12]: error: Buffer is accessed out of bounds: p [bufferAccessOutOfBounds]\n" "[test.cpp:2:13]: note: Assign p, buffer with size 10\n" "[test.cpp:3:12]: note: Buffer overrun\n", errout_str()); @@ -3698,26 +3699,26 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " u8 str[256];\n" " mystrcpy(str, \"abcd\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " u8 str[2];\n" " mystrcpy(str, \"abcd\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); // The same for structs, where the message comes from a different check check("void f() {\n" " struct { u8 str[256]; } ms;\n" " mystrcpy(ms.str, \"abcd\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " struct { u8 str[2]; } ms;\n" " mystrcpy(ms.str, \"abcd\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:16]: (error) Buffer is accessed out of bounds: ms.str [bufferAccessOutOfBounds]\n", errout_str()); } @@ -4288,13 +4289,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[10];\n" " mymemset(c, 0, 10);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[10];\n" " mymemset(c, 0, 11);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("struct S {\n" @@ -4303,13 +4304,13 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " S s;\n" " mymemset(s.a, 0, 10);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:6:15]: (error) Buffer is accessed out of bounds: s.a [bufferAccessOutOfBounds]\n", errout_str()); check("void foo() {\n" " char s[10];\n" " mymemset(s, 0, '*');\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) The size argument is given as a char constant.\n" "[test.cpp:3:14]: (error) Buffer is accessed out of bounds: s [bufferAccessOutOfBounds]\n", "[test.cpp:3:14]: (error) Buffer is accessed out of bounds: s [bufferAccessOutOfBounds]\n", errout_str()); @@ -4317,65 +4318,65 @@ class TestBufferOverrun : public TestFixture { check("void f(void) {\n" " char a[10];\n" " mymemset(a+5, 0, 10);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", "", errout_str()); // Ticket #909 check("void f(void) {\n" " char str[] = \"abcd\";\n" " mymemset(str, 0, 6);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(void) {\n" " char str[] = \"abcd\";\n" " mymemset(str, 0, 5);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f(void) {\n" " wchar_t str[] = L\"abcd\";\n" " mymemset(str, 0, 21);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(void) {\n" " wchar_t str[] = L\"abcd\";\n" " mymemset(str, 0, 20);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); // ticket #1659 - overflowing variable when using memcpy check("void f(void) {\n" " char c;\n" " mymemset(&c, 0, 4);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &c [bufferAccessOutOfBounds]\n", errout_str()); // ticket #2121 - buffer access out of bounds when using uint32_t check("void f(void) {\n" " unknown_type_t buf[4];\n" " mymemset(buf, 0, 100);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); // #3124 - multidimensional array check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 5 * 6);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 6 * 6);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: b [bufferAccessOutOfBounds]\n", errout_str()); check("int main() {\n" " char b[5][6];\n" " mymemset(b, 0, 31);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:14]: (error) Buffer is accessed out of bounds: b [bufferAccessOutOfBounds]\n", errout_str()); // #4968 - not standard function @@ -4384,26 +4385,26 @@ class TestBufferOverrun : public TestFixture { " foo.mymemset(str, 0, 100);\n" " foo::mymemset(str, 0, 100);\n" " std::mymemset(str, 0, 100);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:5:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", "", errout_str()); // #5257 - check strings check("void f() {\n" " mymemset(\"abc\", 0, 20);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Buffer is accessed out of bounds.\n", "", errout_str()); check("void f() {\n" " mymemset(temp, \"abc\", 4);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #6816 - fp when array has known string value " char c[10] = \"c\";\n" " mymemset(c, 0, 10);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); } @@ -4425,43 +4426,43 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[7];\n" " mystrncpy(c, \"hello\", 7);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[6];\n" " mystrncpy(c,\"hello\",6);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[5];\n" " mystrncpy(c,\"hello\",6);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char c[6];\n" " mystrncpy(c,\"hello!\",7);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); check("void f(unsigned int addr) {\n" " memset((void *)addr, 0, 1000);\n" - "}", dinit(CheckOptions, $.s = &settings0)); + "}", settings0); // TODO: use settings? ASSERT_EQUALS("", errout_str()); check("struct AB { char a[10]; };\n" "void foo(AB *ab) {\n" " mystrncpy(x, ab->a, 100);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void a(char *p) { mystrncpy(p,\"hello world!\",10); }\n" // #3168 "void b() {\n" " char buf[5];\n" " a(buf);" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (error) Buffer is accessed out of bounds: buf\n", "", errout_str()); @@ -4487,13 +4488,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char str[3];\n" " mysprintf(str, \"test\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char str[5];\n" " mysprintf(str, \"%s\", \"abcde\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("int getnumber();\n" @@ -4501,51 +4502,51 @@ class TestBufferOverrun : public TestFixture { "{\n" " char str[5];\n" " mysprintf(str, \"%d: %s\", getnumber(), \"abcde\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:5:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f() {\n" " char str[5];\n" " mysprintf(str, \"test%s\", \"\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char *str = new char[5];\n" " mysprintf(str, \"abcde\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:15]: (error) Buffer is accessed out of bounds: str [bufferAccessOutOfBounds]\n", errout_str()); check("void f(int condition) {\n" " char str[5];\n" " mysprintf(str, \"test%s\", condition ? \"12\" : \"34\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f(int condition) {\n" " char str[5];\n" " mysprintf(str, \"test%s\", condition ? \"12\" : \"345\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("error", "", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo x;\n" " mysprintf(x.a, \"aa\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:4:14]: (error) Buffer is accessed out of bounds: x.a [bufferAccessOutOfBounds]\n", errout_str()); // ticket #900 check("void f() {\n" " char *a = new char(30);\n" " mysprintf(a, \"a\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", errout_str()); check("void f(char value) {\n" " char *a = new char(value);\n" " mysprintf(a, \"a\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: a [bufferAccessOutOfBounds]\n", errout_str()); // This is out of bounds if 'sizeof(ABC)' is 1 (No padding) @@ -4553,21 +4554,21 @@ class TestBufferOverrun : public TestFixture { "void f() {\n" " struct Foo *x = malloc(sizeof(Foo));\n" " mysprintf(x->a, \"aa\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); TODO_ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", "", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo *x = malloc(sizeof(Foo) + 10);\n" " mysprintf(x->a, \"aa\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo x;\n" " mysprintf(x.a, \"aa\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:4:14]: (error) Buffer is accessed out of bounds: x.a [bufferAccessOutOfBounds]\n", errout_str()); check("struct Foo {\n" // #6668 - unknown size @@ -4576,7 +4577,7 @@ class TestBufferOverrun : public TestFixture { "};" "void Foo::f() {\n" " mysprintf(a, \"abcd\");\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); } @@ -4597,13 +4598,13 @@ class TestBufferOverrun : public TestFixture { check("void f() {\n" " char c[5];\n" " myfread(c, 1, 5, stdin);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c[5];\n" " myfread(c, 1, 6, stdin);\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:13]: (error) Buffer is accessed out of bounds: c [bufferAccessOutOfBounds]\n", errout_str()); } @@ -5276,9 +5277,9 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("", errout_str()); } -#define ctu(code) ctu_(code, __FILE__, __LINE__) +#define ctu(...) ctu_(__FILE__, __LINE__, __VA_ARGS__) template - void ctu_(const char (&code)[size], const char* file, int line) { + void ctu_(const char* file, int line, const char (&code)[size]) { // Tokenize.. SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -5729,7 +5730,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe(pipefd) == -1) {\n" " return;\n" " }\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: pipefd [bufferAccessOutOfBounds]\n", errout_str()); check("void f(){\n" @@ -5737,7 +5738,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe(pipefd) == -1) {\n" " return;\n" " }\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); check("void f(){\n" @@ -5745,7 +5746,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe((int*)pipefd) == -1) {\n" " return;\n" " }\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("[test.cpp:3:10]: (error) Buffer is accessed out of bounds: (int*)pipefd [bufferAccessOutOfBounds]\n", errout_str()); check("void f(){\n" @@ -5753,7 +5754,7 @@ class TestBufferOverrun : public TestFixture { "if (pipe((int*)pipefd) == -1) {\n" " return;\n" " }\n" - "}", dinit(CheckOptions, $.s = &settings)); + "}", settings); ASSERT_EQUALS("", errout_str()); } }; diff --git a/test/testclass.cpp b/test/testclass.cpp index aa28ab96fb2..8b4af350178 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -35,6 +35,7 @@ class TestClass : public TestFixture { private: const Settings settings0 = settingsBuilder().severity(Severity::style).library("std.cfg").build(); + const Settings settings0_i = settingsBuilder(settings0).certainty(Certainty::inconclusive).build(); const Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build(); const Settings settings2 = settingsBuilder().severity(Severity::style).library("std.cfg").certainty(Certainty::inconclusive).build(); const Settings settings3 = settingsBuilder().severity(Severity::style).library("std.cfg").severity(Severity::warning).build(); @@ -3655,16 +3656,19 @@ class TestClass : public TestFixture { struct CheckConstOptions { - const Settings *s = nullptr; bool inconclusive = true; }; #define checkConst(...) checkConst_(__FILE__, __LINE__, __VA_ARGS__) template void checkConst_(const char* file, int line, const char (&code)[size], const CheckConstOptions& options = make_default_obj()) { - const Settings settings = settingsBuilder(options.s ? *options.s : settings0).certainty(Certainty::inconclusive, options.inconclusive).build(); + const Settings& settings = options.inconclusive ? settings0_i : settings0; - // Tokenize.. + checkConst_(file, line, code, settings); + } + + template + void checkConst_(const char* file, int line, const char (&code)[size], const Settings& settings) { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -7747,7 +7751,7 @@ class TestClass : public TestFixture { } void qualifiedNameMember() { // #10872 - const Settings s = settingsBuilder().severity(Severity::style).debugwarnings().library("std.cfg").build(); + const Settings s = settingsBuilder().severity(Severity::style).debugwarnings().library("std.cfg").certainty(Certainty::inconclusive).build(); checkConst("struct data {};\n" " struct S {\n" " std::vector std;\n" @@ -7755,7 +7759,7 @@ class TestClass : public TestFixture { "};\n" "void S::f() {\n" " std::vector::const_iterator end = std.end();\n" - "}\n", dinit(CheckConstOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:6:9]: (style, inconclusive) Technically the member function 'S::f' can be const. [functionConst]\n", errout_str()); } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index fe3a3586f31..dd4d52848ea 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -130,16 +130,18 @@ class TestCondition : public TestFixture { struct CheckOptions { - const Settings* s = nullptr; bool cpp = true; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings& settings = options.s ? *options.s : settings0; + check_(file, line, code, settings0, options.cpp); + } - SimpleTokenizer2 tokenizer(settings, *this, code, options.cpp ? "test.cpp" : "test.c"); + template + void check_(const char* file, int line, const char (&code)[size], const Settings& settings, bool cpp = true) { + SimpleTokenizer2 tokenizer(settings, *this, code, cpp ? "test.cpp" : "test.c"); // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); @@ -515,7 +517,16 @@ class TestCondition : public TestFixture { errout_str()); } -#define checkPureFunction(code) checkPureFunction_(code, __FILE__, __LINE__) +#define checkPureFunction(...) checkPureFunction_(__FILE__, __LINE__, __VA_ARGS__) + template + void checkPureFunction_(const char* file, int line, const char (&code)[size]) { + // Tokenize.. + SimpleTokenizer tokenizer(settings1, *this); + ASSERT_LOC(tokenizer.tokenize(code), file, line); + + runChecks(tokenizer, this); + } + void multicompare() { check("void foo(int x)\n" "{\n" @@ -574,15 +585,6 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("", errout_str()); } - template - void checkPureFunction_(const char (&code)[size], const char* file, int line) { - // Tokenize.. - SimpleTokenizer tokenizer(settings1, *this); - ASSERT_LOC(tokenizer.tokenize(code), file, line); - - runChecks(tokenizer, this); - } - void overlappingElseIfCondition() { check("void f(int a, int &b) {\n" " if (a) { b = 1; }\n" @@ -1309,27 +1311,27 @@ class TestCondition : public TestFixture { const Settings s = settingsBuilder(settings0).certainty(Certainty::inconclusive).build(); check("void f(char x) {\n" " if (x == '1' || x == '2') {}\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("", errout_str()); check("void f(char x) {\n" " if (x == '1' && x == '2') {}\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:2:16]: (warning) Logical conjunction always evaluates to false: x == '1' && x == '2'. [incorrectLogicOperator]\n", errout_str()); check("int f(char c) {\n" " return (c >= 'a' && c <= 'z');\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("", errout_str()); check("int f(char c) {\n" " return (c <= 'a' && c >= 'z');\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:2:20]: (warning, inconclusive) Logical conjunction always evaluates to false: c <= 'a' && c >= 'z'. [incorrectLogicOperator]\n", errout_str()); check("int f(char c) {\n" " return (c <= 'a' && c >= 'z');\n" - "}"); + "}"); // TODO: use s? ASSERT_EQUALS("[test.cpp:2:13] -> [test.cpp:2:25]: (style) Return value 'c>='z'' is always false [knownConditionTrueFalse]\n", errout_str()); } @@ -6142,65 +6144,65 @@ class TestCondition : public TestFixture { check("void f(unsigned char c) {\n" " if (c == 256) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(unsigned char* b, int i) {\n" // #6372 " if (b[i] == 256) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:15]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(unsigned char c) {\n" " if (c == 255) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(bool b) {\n" " if (b == true) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); // #10372 check("void f(signed char x) {\n" " if (x == 0xff) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(short x) {\n" " if (x == 0xffff) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:12]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(int x) {\n" " if (x == 0xffffffff) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(long x) {\n" " if (x == ~0L) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(long long x) {\n" " if (x == ~0LL) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("int f(int x) {\n" " const int i = 0xFFFFFFFF;\n" " if (x == i) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " char c;\n" " if ((c = foo()) != -1) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("", errout_str()); check("void f(int x) {\n" " if (x < 3000000000) {}\n" - "}", dinit(CheckOptions, $.s = &settingsUnix64)); + "}", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:11]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true. [compareValueOutOfTypeRangeError]\n", errout_str()); check("void f(const signed char i) {\n" // #8545 @@ -6210,7 +6212,7 @@ class TestCondition : public TestFixture { " if (i < +128) {}\n" // warn " if (i <= +127) {}\n" // warn " if (i <= +126) {}\n" - "}\n", dinit(CheckOptions, $.s = &settingsUnix64)); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:15]: (style) Comparing expression of type 'const signed char' against value -129. Condition is always true. [compareValueOutOfTypeRangeError]\n" "[test.cpp:3:15]: (style) Comparing expression of type 'const signed char' against value -128. Condition is always true. [compareValueOutOfTypeRangeError]\n" "[test.cpp:5:15]: (style) Comparing expression of type 'const signed char' against value 128. Condition is always true. [compareValueOutOfTypeRangeError]\n" @@ -6234,7 +6236,7 @@ class TestCondition : public TestFixture { " if (255 > u) {}\n" " if (255 <= u) {}\n" " if (255 >= u) {}\n" // warn - "}\n", dinit(CheckOptions, $.s = &settingsUnix64)); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:3:14]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false. [compareValueOutOfTypeRangeError]\n" "[test.cpp:4:14]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true. [compareValueOutOfTypeRangeError]\n" "[test.cpp:6:14]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false. [compareValueOutOfTypeRangeError]\n" @@ -6247,7 +6249,7 @@ class TestCondition : public TestFixture { check("void f(bool b) {\n" // #14037 " if (b != 2) {}\n" - "}\n", dinit(CheckOptions, $.s = &settingsUnix64)); + "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:14]: (style) Comparing expression of type 'bool' against value 2. Condition is always true. [compareValueOutOfTypeRangeError]\n", errout_str()); } diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 1aaccce83d6..04e18f65e2e 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -31,19 +31,23 @@ class TestConstructors : public TestFixture { private: const Settings settings = settingsBuilder().severity(Severity::style).severity(Severity::warning).build(); + const Settings settings_i = settingsBuilder(settings).certainty(Certainty::inconclusive).build(); struct CheckOptions { bool inconclusive = false; - const Settings* s = nullptr; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings settings1 = settingsBuilder(options.s ? *options.s : settings).certainty(Certainty::inconclusive, options.inconclusive).build(); + const Settings settings1 = options.inconclusive ? settings_i : settings; - // Tokenize.. + check_(file, line, code, settings1); + } + + template + void check_(const char* file, int line, const char (&code)[size], const Settings& settings1) { SimpleTokenizer tokenizer(settings1, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -1593,7 +1597,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ }", dinit(CheckOptions, $.s = &s)); + "{ }", s); ASSERT_EQUALS("[test.cpp:7:7]: (warning) Member variable 'Fred::var' is not initialized in the constructor. [uninitMemberVarPrivate]\n", errout_str()); } @@ -1606,7 +1610,7 @@ class TestConstructors : public TestFixture { " Fred();\n" "};\n" "Fred::Fred()\n" - "{ }", dinit(CheckOptions, $.s = &s)); + "{ }", s); ASSERT_EQUALS("", errout_str()); } } @@ -2064,7 +2068,7 @@ class TestConstructors : public TestFixture { " d = rhs.get();\n" " }\n" " double d;\n" - "};", dinit(CheckOptions, $.s = &s)); + "};", s); ASSERT_EQUALS("", errout_str()); check("struct S {\n" // #8485 @@ -2098,7 +2102,7 @@ class TestConstructors : public TestFixture { check("struct S {\n" " S& operator=(const S& s) { return *this; }\n" " std::mutex m;\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("", errout_str()); } @@ -3046,7 +3050,7 @@ class TestConstructors : public TestFixture { check("struct C {\n" // #13989 " C() = default;\n" " std::list::const_iterator it;\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Member variable 'C::it' is not initialized in the constructor. [uninitMemberVar]\n", errout_str()); } @@ -3257,7 +3261,7 @@ class TestConstructors : public TestFixture { " std::array e;\n" " std::array f;\n" "S() {}\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("[test.cpp:10:1]: (warning) Member variable 'S::a' is not initialized in the constructor. [uninitMemberVar]\n" "[test.cpp:10:1]: (warning) Member variable 'S::b' is not initialized in the constructor. [uninitMemberVar]\n" @@ -3689,7 +3693,7 @@ class TestConstructors : public TestFixture { check("class Foo {\n" " int foo;\n" " Foo() { }\n" - "};", dinit(CheckOptions, $.s = &s)); + "};", s); ASSERT_EQUALS("", errout_str()); } @@ -3698,7 +3702,7 @@ class TestConstructors : public TestFixture { check("class Foo {\n" " int foo;\n" " Foo() { }\n" - "};", dinit(CheckOptions, $.s = &s)); + "};", s); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Member variable 'Foo::foo' is not initialized in the constructor. [uninitMemberVarPrivate]\n", errout_str()); } } @@ -3760,7 +3764,7 @@ class TestConstructors : public TestFixture { " Fred() { }\n" "private:\n" " int x;\n" - "};", dinit(CheckOptions, $.s = &s)); + "};", s); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 5bb8790cb73..42537ca36fb 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -314,8 +314,7 @@ class TestErrorLogger : public TestFixture { } } - #define testReportType(reportType, severity, errorId, expectedClassification, expectedGuideline) \ - testReportType_(__FILE__, __LINE__, reportType, severity, errorId, expectedClassification, expectedGuideline) + #define testReportType(...) testReportType_(__FILE__, __LINE__, __VA_ARGS__) void testReportType_(const char *file, int line, ReportType reportType, Severity severity, const std::string &errorId, const std::string &expectedClassification, const std::string &expectedGuideline) const { diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index db52237f994..da589c765fe 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -117,16 +117,17 @@ class TestFunctions : public TestFixture { struct CheckOptions { bool cpp = true; - const Settings* s = nullptr; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings& s = options.s ? *options.s : settings; + check_(file, line, code, settings, options.cpp); + } - // Tokenize.. - SimpleTokenizer tokenizer(s, *this, options.cpp); + template + void check_(const char* file, int line, const char (&code)[size], const Settings& s, bool cpp = true) { + SimpleTokenizer tokenizer(s, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); runChecks(tokenizer, this); @@ -279,19 +280,19 @@ class TestFunctions : public TestFixture { check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", dinit(CheckOptions, $.s = &s)); // #4382 - there are no VLAs in C++ + "}", s); // #4382 - there are no VLAs in C++ ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", dinit(CheckOptions, $.cpp = false, $.s = &s)); // #7558 - no alternative to alloca in C89 + "}", s, false); // #7558 - no alternative to alloca in C89 ASSERT_EQUALS("", errout_str()); check("void f()\n" "{\n" " char *x = alloca(10);\n" - "}", dinit(CheckOptions, $.cpp = false, $.s = &s)); + "}", s, false); ASSERT_EQUALS("", errout_str()); } @@ -776,7 +777,7 @@ class TestFunctions : public TestFixture { " memmove(&tgt, &src, sizeof src);\n" " memset(&tgt + sizeof src, ' ', sizeof tgt - sizeof src);\n" " }\n" - "}\n", dinit(CheckOptions, $.cpp = false, $.s = &settingsUnix32)); + "}\n", settingsUnix32, false); ASSERT_EQUALS("", errout_str()); } @@ -1328,67 +1329,67 @@ class TestFunctions : public TestFixture { check("void foo() {\n" " mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:2:3]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void foo() {\n" " foo::mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:2:8]: (warning) Return value of function foo::mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void f() {\n" " foo x;\n" " x.mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Return value of function x.mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("bool mystrcmp(char* a, char* b);\n" // cppcheck sees a custom strcmp definition, but it returns a value. Assume it is the one specified in the library. "void foo() {\n" " mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:3:5]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void mystrcmp(char* a, char* b);\n" // cppcheck sees a custom strcmp definition which returns void! "void foo() {\n" " mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " class mystrcmp { mystrcmp() {} };\n" // strcmp is a constructor definition here - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " return mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " return foo::mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " if(mystrcmp(a, b));\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" " bool b = mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); // #6194 check("void foo() {\n" " MyStrCmp mystrcmp(x, y);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); // #6197 check("void foo() {\n" " abc::def.mystrcmp(a,b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); // #6233 @@ -1400,29 +1401,29 @@ class TestFunctions : public TestFixture { " lambda(13.3);\n" " return 0;\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #6669 check("void foo(size_t size) {\n" " void * res{malloc(size)};\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #7447 check("void foo() {\n" " int x{mystrcmp(a,b)};\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); // #7905 check("void foo() {\n" " int x({mystrcmp(a,b)});\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("", errout_str()); check("void foo() {\n" // don't crash " DEBUG(123)(mystrcmp(a,b))(fd);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); check("struct teststruct {\n" " int testfunc1() __attribute__ ((warn_unused_result)) { return 1; }\n" " [[nodiscard]] int testfunc2() { return 1; }\n" @@ -1433,7 +1434,7 @@ class TestFunctions : public TestFixture { " TestStruct1.testfunc1();\n" " TestStruct1.testfunc2();\n" " return 0;\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:4:18]: (warning) Return value of function testfunc1() is not used. [ignoredReturnValue]\n" "[test.cpp:4:31]: (warning) Return value of function testfunc2() is not used. [ignoredReturnValue]\n" "[test.cpp:8:17]: (warning) Return value of function TestStruct1.testfunc1() is not used. [ignoredReturnValue]\n" @@ -1444,7 +1445,7 @@ class TestFunctions : public TestFixture { " std::tuple c{std::move(d)};\n" " return std::get<0>(c);\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("", errout_str()); // TODO: use settings2? check("struct A { int x; };\n" "template \n" @@ -1452,25 +1453,25 @@ class TestFunctions : public TestFixture { " return {std::move(x), static_cast(xs)...};\n" "}\n" "A g() { return f(1); }"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("", errout_str()); // TODO: use settings2? // #8412 - unused operator result check("void foo() {\n" " !mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:2:4]: (warning) Return value of function mystrcmp() is not used. [ignoredReturnValue]\n", errout_str()); check("void f(std::vector v) {\n" " delete *v.begin();\n" "}\n"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("", errout_str()); // TODO: use settings2? check("int __attribute__((pure)) p_foo(int);\n" // #12697 "int __attribute__((const)) c_foo(int);\n" "void f() {\n" " p_foo(0);\n" " c_foo(0);\n" - "}\n"); + "}\n"); // TODO: use settings2? ASSERT_EQUALS("[test.cpp:4:5]: (warning) Return value of function p_foo() is not used. [ignoredReturnValue]\n" "[test.cpp:5:5]: (warning) Return value of function c_foo() is not used. [ignoredReturnValue]\n", errout_str()); @@ -1489,7 +1490,7 @@ class TestFunctions : public TestFixture { check("void foo() {\n" " mystrcmp(a, b);\n" - "}", dinit(CheckOptions, $.s = &settings2)); + "}", settings2); ASSERT_EQUALS("[test.cpp:2:3]: (style) Error code from the return value of function mystrcmp() is not used. [ignoredReturnErrorCode]\n", errout_str()); } @@ -1595,16 +1596,16 @@ class TestFunctions : public TestFixture { { const Settings s = settingsBuilder().c(Standards::C89).build(); - check(code, dinit(CheckOptions, $.cpp = false, $.s = &s)); // c code (c89) + check(code, s, false); // c code (c89) ASSERT_EQUALS("[test.c:1:17]: (error) Found an exit path from function with non-void return type that has missing return statement [missingReturn]\n", errout_str()); } { const Settings s = settingsBuilder().c(Standards::C99).build(); - check(code, dinit(CheckOptions, $.cpp = false, $.s = &s)); // c code (c99) + check(code, s, false); // c code (c99) ASSERT_EQUALS("", errout_str()); - check(code, dinit(CheckOptions, $.s = &s)); // c++ code + check(code, s); // c++ code ASSERT_EQUALS("", errout_str()); } } @@ -1954,12 +1955,12 @@ class TestFunctions : public TestFixture { check("void f() {\n" " lib_func();" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:2:5]: (information) --check-library: There is no matching configuration for function lib_func() [checkLibraryFunction]\n", errout_str()); check("void f(void* v) {\n" " lib_func(v);" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:2:5]: (information) --check-library: There is no matching configuration for function lib_func() [checkLibraryFunction]\n", errout_str()); // #10105 @@ -1975,7 +1976,7 @@ class TestFunctions : public TestFixture { "\n" " void testFunctionReturnType() {\n" " }\n" - "};", dinit(CheckOptions, $.s = &s)); + "};", s); ASSERT_EQUALS("", errout_str()); // #11183 @@ -1985,7 +1986,7 @@ class TestFunctions : public TestFixture { "\n" "void f() {\n" " cb(std::string(\"\"));\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); TODO_ASSERT_EQUALS("", "[test.cpp:6:5]: (information) --check-library: There is no matching configuration for function cb() [checkLibraryFunction]\n", errout_str()); // #7375 @@ -1993,38 +1994,38 @@ class TestFunctions : public TestFixture { " struct S { int i; char c; };\n" " size_t s = sizeof(S);\n" " static_assert(s == 9);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f(char) {}\n" "void g() {\n" " f(int8_t(1));\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f(std::uint64_t& u) {\n" " u = std::uint32_t(u) * std::uint64_t(100);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); - check("void f() { throw(1); }\n", dinit(CheckOptions, $.s = &s)); // #8958 + check("void f() { throw(1); }\n", s); // #8958 ASSERT_EQUALS("", errout_str()); check("using namespace std;\n" - "void f() { throw range_error(\"abc\"); }\n", dinit(CheckOptions, $.s = &s)); + "void f() { throw range_error(\"abc\"); }\n", s); ASSERT_EQUALS("", errout_str()); check("class C {\n" // #9002 "public:\n" " static int f() { return 1; }\n" "};\n" - "void g() { C::f(); }\n", dinit(CheckOptions, $.s = &s)); + "void g() { C::f(); }\n", s); ASSERT_EQUALS("", errout_str()); check("void f(const std::vector& v) {\n" // #11223 " for (const auto& s : v)\n" " s.find(\"\");\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("[test.cpp:3:11]: (warning) Return value of function s.find() is not used. [ignoredReturnValue]\n", errout_str()); check("void f() {\n" @@ -2034,19 +2035,19 @@ class TestFunctions : public TestFixture { " q->push_back(1);\n" " auto* r = new std::vector;\n" " r->push_back(1);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " auto p = std::make_shared>();\n" " p->push_back(1);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f(std::vector>& v) {\n" " auto it = v.begin();\n" " it->push_back(1);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2056,7 +2057,7 @@ class TestFunctions : public TestFixture { " w.push_back(1);\n" " auto x = std::vector(1);\n" " x.push_back(1);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2064,7 +2065,7 @@ class TestFunctions : public TestFixture { " p->push_back(1);\n" " auto q{ std::make_shared>{} };\n" " q->push_back(1);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); TODO_ASSERT_EQUALS("", "[test.cpp:2:5]: (debug) auto token with no type. [autoNoType]\n" "[test.cpp:4:5]: (debug) auto token with no type. [autoNoType]\n" @@ -2077,12 +2078,12 @@ class TestFunctions : public TestFixture { " std::list::iterator it;\n" " for (it = l.begin(); it != l.end(); ++it)\n" " it->g(0);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", filter_valueflow(errout_str())); check("auto f() {\n" " return std::runtime_error(\"abc\");\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); TODO_ASSERT_EQUALS("", "[test.cpp:1:1]: (debug) auto token with no type. [autoNoType]\n", errout_str()); @@ -2095,7 +2096,7 @@ class TestFunctions : public TestFixture { "void S::f(int i) const {\n" " for (const std::shared_ptr& c : v)\n" " c->f(i);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("namespace N {\n" @@ -2104,29 +2105,29 @@ class TestFunctions : public TestFixture { "void f() {\n" " const auto& t = N::S::s;\n" " if (t.find(\"abc\") != t.end()) {}\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", filter_valueflow(errout_str())); check("void f(std::vector>>& v, int i, int j) {\n" " auto& s = v[i][j];\n" " s.insert(0);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("int f(const std::vector& v, int i, char c) {\n" " const auto& s = v[i];\n" " return s.find(c);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" // #11604 " int (*g)() = nullptr;\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" " INT (*g)() = nullptr;\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("struct T;\n" @@ -2135,13 +2136,13 @@ class TestFunctions : public TestFixture { " auto p = get();\n" " p->h(i);\n" " p.reset(nullptr);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("[test.cpp:5:8]: (information) --check-library: There is no matching configuration for function T::h() [checkLibraryFunction]\n", errout_str()); check("struct S : std::vector {\n" " void f(int i) { push_back(i); }\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("", errout_str()); check("void f() {\n" @@ -2151,18 +2152,18 @@ class TestFunctions : public TestFixture { " auto h{ []() -> std::string { return \"xyz\"; } };\n" " auto t = h();\n" " if (t.at(0)) {}\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("", filter_valueflow(errout_str())); check("::std::string f(const char* c) {\n" // #12365 " return ::std::string(c);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); check("template \n" "struct S : public std::vector {\n" " void resize(size_t n) { std::vector::resize(n); }\n" - "};\n", dinit(CheckOptions, $.s = &s)); + "};\n", s); ASSERT_EQUALS("", errout_str()); check("struct P {\n" // #13105 @@ -2173,7 +2174,7 @@ class TestFunctions : public TestFixture { " auto it = m->find(i);\n" " const bool b = it != m->end();\n" " return b;\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); TODO_ASSERT_EQUALS("", "[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n", errout_str()); } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index d5549cb26cf..c3f0d25ca56 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -276,18 +276,6 @@ class TestGarbage : public TestFixture { } #define checkCodeInternal(...) checkCodeInternal_(__FILE__, __LINE__, __VA_ARGS__) - template - std::string checkCode(const char (&code)[size], bool cpp = true) { - // double the tests - run each example as C as well as C++ - - // run alternate check first. It should only ensure stability - so we catch exceptions here. - try { - (void)checkCodeInternal(code, !cpp); - } catch (const InternalError&) {} - - return checkCodeInternal(code, cpp); - } - template std::string checkCodeInternal_(const char* file, int line, const char (&code)[size], bool cpp) { // tokenize.. @@ -302,6 +290,18 @@ class TestGarbage : public TestFixture { return tokenizer.tokens()->stringifyList(false, false, false, true, false, nullptr, nullptr); } + template + std::string checkCode(const char (&code)[size], bool cpp = true) { + // double the tests - run each example as C as well as C++ + + // run alternate check first. It should only ensure stability - so we catch exceptions here. + try { + (void)checkCodeInternal(code, !cpp); + } catch (const InternalError&) {} + + return checkCodeInternal(code, cpp); + } + #define getSyntaxError(...) getSyntaxError_(__FILE__, __LINE__, __VA_ARGS__) template std::string getSyntaxError_(const char* file, int line, const char (&code)[size]) { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 1339e6868ac..daf738e7b46 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -3224,8 +3224,8 @@ class TestLeakAutoVarRecursiveCountLimit : public TestFixture { #define checkP(...) checkP_(__FILE__, __LINE__, __VA_ARGS__) template - void checkP_(const char* file, int line, const char (&code)[size], bool cpp = false) { - SimpleTokenizer2 tokenizer(settings, *this, code, cpp?"test.cpp":"test.c"); + void checkP_(const char* file, int line, const char (&code)[size]) { + SimpleTokenizer2 tokenizer(settings, *this, code, "test.c"); // Tokenizer.. ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line); diff --git a/test/testlibrary.cpp b/test/testlibrary.cpp index 5ea3a2e7120..a531ac4cba9 100644 --- a/test/testlibrary.cpp +++ b/test/testlibrary.cpp @@ -1012,7 +1012,14 @@ class TestLibrary : public TestFixture { } } -#define LOADLIBERROR(xmldata, errorcode) loadLibError(xmldata, errorcode, __FILE__, __LINE__) +#define LOADLIBERROR(...) loadLibError(__FILE__, __LINE__, __VA_ARGS__) + template + void loadLibError(const char* file, unsigned line, const char (&xmldata)[size], Library::ErrorCode errorcode) const { + Library library; + Library::Error liberr; + assertEquals(file, line, true, LibraryHelper::loadxmldata(library, liberr, xmldata, size-1)); + assertEquals(file, line, true, errorcode == liberr.errorcode); + } void version() const { { @@ -1053,14 +1060,6 @@ class TestLibrary : public TestFixture { } } - template - void loadLibError(const char (&xmldata)[size], Library::ErrorCode errorcode, const char* file, unsigned line) const { - Library library; - Library::Error liberr; - assertEquals(file, line, true, LibraryHelper::loadxmldata(library, liberr, xmldata, size-1)); - assertEquals(file, line, true, errorcode == liberr.errorcode); - } - #define LOADLIB_ERROR_INVALID_RANGE(valid) LOADLIBERROR("\n" \ "\n" \ "\n" \ diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 8f1adfc585d..ee971fd44a8 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4617,9 +4617,9 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout_str()); } -#define ctu(code) ctu_(code, __FILE__, __LINE__) +#define ctu(...) ctu_(__FILE__, __LINE__, __VA_ARGS__) template - void ctu_(const char (&code)[size], const char* file, int line) { + void ctu_(const char* file, int line, const char (&code)[size]) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); diff --git a/test/testother.cpp b/test/testother.cpp index 8f21a7eedea..33ac2308bf6 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -337,7 +337,7 @@ class TestOther : public TestFixture { bool cpp = true; bool inconclusive = true; bool verbose = false; - Settings* settings = nullptr; + Settings* settings = nullptr; // TODO: split from this }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) diff --git a/test/teststl.cpp b/test/teststl.cpp index 6714222cca8..43f5ca2eda5 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -183,16 +183,19 @@ class TestStl : public TestFixture { struct CheckOptions { bool inconclusive = false; - const Settings* s = nullptr; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings* s = options.s ? options.s : (options.inconclusive ? &settings_i : &settings); + const Settings& s = options.inconclusive ? settings_i : settings; - // Tokenize.. - SimpleTokenizer tokenizer(*s, *this); + check_(file, line, code, s); + } + + template + void check_(const char* file, int line, const char (&code)[size], const Settings& s) { + SimpleTokenizer tokenizer(s, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -209,9 +212,9 @@ class TestStl : public TestFixture { runChecks(tokenizer, this); } -#define checkNormal(code) checkNormal_(code, __FILE__, __LINE__) +#define checkNormal(...) checkNormal_(__FILE__, __LINE__, __VA_ARGS__) template - void checkNormal_(const char (&code)[size], const char* file, int line) { + void checkNormal_(const char* file, int line, const char (&code)[size]) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -2643,7 +2646,7 @@ class TestStl : public TestFixture { check("void f() {\n" " const char a[][5] = { \"1\", \"true\", \"on\", \"yes\" };\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); } @@ -2660,7 +2663,7 @@ class TestStl : public TestFixture { "}\n" "void g(const std::vector& w) {\n" " f(-1, w);\n" - "}\n", dinit(CheckOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("[test.cpp:5:9]: warning: Array index -1 is out of bounds. [negativeContainerIndex]\n" "[test.cpp:8:8]: note: Calling function 'f', 1st argument '-1' value is -1\n" "[test.cpp:3:9]: note: Assuming condition is false\n" @@ -3786,7 +3789,7 @@ class TestStl : public TestFixture { "{\n" " if (x.size() == 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:7:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3798,7 +3801,7 @@ class TestStl : public TestFixture { "{\n" " if (x.size() == 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3810,7 +3813,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size() == 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3822,7 +3825,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (0 == x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3834,7 +3837,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size() != 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3846,7 +3849,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (0 != x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3858,7 +3861,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size() > 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3870,7 +3873,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (0 < x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:13]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3882,7 +3885,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size() >= 1) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3894,7 +3897,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size() < 1) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3906,7 +3909,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (1 <= x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3918,7 +3921,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (1 > x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:13]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3930,7 +3933,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:9]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3942,7 +3945,7 @@ class TestStl : public TestFixture { " std::list x;\n" " if (!x.size()) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:10]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3961,7 +3964,7 @@ class TestStl : public TestFixture { " std::list x;\n" " fun(!x.size());\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:10]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -3973,7 +3976,7 @@ class TestStl : public TestFixture { " std::list x;\n" " fun(a && x.size());\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS("[test.cpp:4:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", errout_str()); check(code); ASSERT_EQUALS("", errout_str()); @@ -4010,7 +4013,7 @@ class TestStl : public TestFixture { "{\n" " if (f.x.size() == 0) {}\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS( "[test.cpp:10:11]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n" "[test.cpp:10:11]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", // duplicate @@ -4033,7 +4036,7 @@ class TestStl : public TestFixture { "int main() {\n" " if (zzz->x.size() > 0) { }\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS( "[test.cpp:10:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n" "[test.cpp:10:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", // duplicate @@ -4052,7 +4055,7 @@ class TestStl : public TestFixture { " Zzz * zzz;\n" " if (zzz->x.size() > 0) { }\n" "}"; - check(code, dinit(CheckOptions, $.s = &settingsCpp03)); + check(code, settingsCpp03); ASSERT_EQUALS( "[test.cpp:10:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n" "[test.cpp:10:14]: (performance) Possible inefficient checking for 'x' emptiness. [stlSize]\n", // duplicate @@ -6806,13 +6809,13 @@ class TestStl : public TestFixture { " }\n" "}\n"; s.standards.cpp = Standards::CPP11; - check(code, dinit(CheckOptions, $.s = &s)); + check(code, s); ASSERT_EQUALS("", errout_str()); s.standards.cpp = Standards::CPP14; - check(code, dinit(CheckOptions, $.s = &s)); + check(code, s); ASSERT_EQUALS("", errout_str()); s.standards.cpp = Standards::CPP17; - check(code, dinit(CheckOptions, $.s = &s)); + check(code, s); ASSERT_EQUALS("[test.cpp:3:18]: (performance) Searching before insertion is not necessary. [stlFindInsert]\n", errout_str()); } @@ -6827,7 +6830,7 @@ class TestStl : public TestFixture { " if(x.find(5) == x.end())\n" " x[5] = data;\n" " }\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("", errout_str()); s.standards.cpp = Standards::CPP11; @@ -6839,7 +6842,7 @@ class TestStl : public TestFixture { " if(x.find(5) == x.end())\n" " x[5] = data;\n" " }\n" - "}", dinit(CheckOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("[test.cpp:7:17]: (performance) Searching before insertion is not necessary. Instead of 'x[5]=data' consider using 'x.emplace(5, data);'. [stlFindInsert]\n", errout_str()); check("void foo() {\n" @@ -6850,7 +6853,7 @@ class TestStl : public TestFixture { " if(x.find(5) == x.end())\n" " x[5] = data;\n" " }\n" - "}"); + "}"); // TODO: use s? ASSERT_EQUALS("[test.cpp:7:17]: (performance) Searching before insertion is not necessary. Instead of 'x[5]=data' consider using 'x.try_emplace(5, data);'. [stlFindInsert]\n", errout_str()); } } diff --git a/test/testtype.cpp b/test/testtype.cpp index a076774e109..bf36182c59a 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -48,7 +48,7 @@ class TestType : public TestFixture { struct CheckOptions { - const Settings* settings = nullptr; + const Settings* settings = nullptr; // TODO: split from this Standards::cppstd_t standard = Standards::cppstd_t::CPP11; }; diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 38a3c4de717..b3c988e5b00 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -110,15 +110,17 @@ class TestUninitVar : public TestFixture { struct CheckUninitVarOptions { bool cpp = true; - const Settings *s = nullptr; }; #define checkUninitVar(...) checkUninitVar_(__FILE__, __LINE__, __VA_ARGS__) - void checkUninitVar_(const char* file, int line, const char code[], const CheckUninitVarOptions& options = make_default_obj()) { - const Settings& settings1 =options.s ? *options.s : settings; + template + void checkUninitVar_(const char* file, int line, const char (&code)[size], const CheckUninitVarOptions& options = make_default_obj()) { + checkUninitVar_(file, line, code, settings, options.cpp); + } - // Tokenize.. - SimpleTokenizer tokenizer(settings1, *this, options.cpp); + template + void checkUninitVar_(const char* file, int line, const char (&code)[size], const Settings& settings1, bool cpp = true) { + SimpleTokenizer tokenizer(settings1, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for redundant code.. @@ -126,6 +128,16 @@ class TestUninitVar : public TestFixture { checkuninitvar.check(); } + // TODO: get rid of this + void checkUninitVar_(const char* file, int line, const std::string& code) { + SimpleTokenizer tokenizer(settings, *this); + ASSERT_LOC(tokenizer.tokenize(code), file, line); + + // Check for redundant code.. + CheckUninitVar checkuninitvar(&tokenizer, &settings, this); + checkuninitvar.check(); + } + void uninitvar1() { // extracttests.start: int b; int c; @@ -845,7 +857,7 @@ class TestUninitVar : public TestFixture { checkUninitVar("void f() {\n" " Fred _tm;\n" " _tm.dostuff();\n" - "}", dinit(CheckUninitVarOptions, $.s = &s)); + "}", s); ASSERT_EQUALS("", errout_str()); } @@ -2435,18 +2447,18 @@ class TestUninitVar : public TestFixture { void func_uninit_var() { const std::string funca("int a(int x) { return x + x; }"); - checkUninitVar((funca + - "void b() {\n" - " int x;\n" - " a(x);\n" - "}").c_str()); + checkUninitVar(funca + + "void b() {\n" + " int x;\n" + " a(x);\n" + "}"); ASSERT_EQUALS("[test.cpp:3:7]: (error) Uninitialized variable: x [legacyUninitvar]\n", errout_str()); - checkUninitVar((funca + - "void b() {\n" - " int *p;\n" - " a(*p);\n" - "}").c_str()); + checkUninitVar(funca + + "void b() {\n" + " int *p;\n" + " a(*p);\n" + "}"); ASSERT_EQUALS("[test.cpp:3:8]: (error) Uninitialized variable: p [legacyUninitvar]\n", errout_str()); } @@ -2456,19 +2468,19 @@ class TestUninitVar : public TestFixture { const std::string funca("void a(int *p) { *p = 0; }"); // ok - initialized pointer - checkUninitVar((funca + - "void b() {\n" - " int buf[10];\n" - " a(buf);\n" - "}").c_str()); + checkUninitVar(funca + + "void b() {\n" + " int buf[10];\n" + " a(buf);\n" + "}"); ASSERT_EQUALS("", errout_str()); // not ok - uninitialized pointer - checkUninitVar((funca + - "void b() {\n" - " int *p;\n" - " a(p);\n" - "}").c_str()); + checkUninitVar(funca + + "void b() {\n" + " int *p;\n" + " a(p);\n" + "}"); ASSERT_EQUALS("[test.cpp:3:7]: (error) Uninitialized variable: p [legacyUninitvar]\n", errout_str()); } @@ -3591,6 +3603,17 @@ class TestUninitVar : public TestFixture { } #define valueFlowUninit(...) valueFlowUninit_(__FILE__, __LINE__, __VA_ARGS__) + template + void valueFlowUninit_(const char* file, int line, const char (&code)[size], bool cpp = true) + { + SimpleTokenizer tokenizer(settings, *this, cpp); + ASSERT_LOC(tokenizer.tokenize(code), file, line); + + // Check for redundant code.. + CheckUninitVar checkuninitvar(&tokenizer, &settings, this); + (checkuninitvar.valueFlowUninit)(); + } + void valueFlowUninit2_value() { valueFlowUninit("void f() {\n" @@ -3600,8 +3623,7 @@ class TestUninitVar : public TestFixture { " if (y != 0) return;\n" " i++;\n" " }\n" - "}", - true); + "}"); ASSERT_EQUALS("", errout_str()); valueFlowUninit("void f() {\n" @@ -3611,8 +3633,7 @@ class TestUninitVar : public TestFixture { " if (y != 0) return;\n" " i++;\n" " }\n" - "}", - true); + "}"); ASSERT_EQUALS("", errout_str()); valueFlowUninit("void f() {\n" @@ -3881,8 +3902,7 @@ class TestUninitVar : public TestFixture { valueFlowUninit("void f() {\n" " int x;\n" " char *p = (char*)&x + 1;\n" - "}", - true); + "}"); ASSERT_EQUALS("", errout_str()); valueFlowUninit("void f() {\n" @@ -4588,7 +4608,7 @@ class TestUninitVar : public TestFixture { " struct AB ab;\n" " uninitvar_funcArgInTest(&ab);\n" " x = ab;\n" - "}\n", dinit(CheckUninitVarOptions, $.cpp = false, $.s = &s)); + "}\n", s, false); ASSERT_EQUALS("[test.c:5:9]: (error) Uninitialized struct member: ab.a [uninitStructMember]\n", errout_str()); checkUninitVar("struct AB { int a; };\n" @@ -4596,7 +4616,7 @@ class TestUninitVar : public TestFixture { " struct AB ab;\n" " uninitvar_funcArgOutTest(&ab);\n" " x = ab;\n" - "}\n", dinit(CheckUninitVarOptions, $.cpp = false, $.s = &s)); + "}\n", s, false); ASSERT_EQUALS("", errout_str()); } @@ -5414,7 +5434,7 @@ class TestUninitVar : public TestFixture { " i = 0;\n" " return i;\n" " } while (0);\n" - "}\n", dinit(CheckUninitVarOptions, $.s = &s)); + "}\n", s); ASSERT_EQUALS("", errout_str()); } @@ -5467,18 +5487,27 @@ class TestUninitVar : public TestFixture { TODO_ASSERT_EQUALS("", "[test.c:4:14]: (error) Uninitialized variable: d [legacyUninitvar]\n", errout_str()); } +#define ctu(...) ctu_(__FILE__, __LINE__, __VA_ARGS__) template - void valueFlowUninit_(const char* file, int line, const char (&code)[size], bool cpp = true) - { - SimpleTokenizer tokenizer(settings, *this, cpp); + void ctu_(const char* file, int line, const char (&code)[size]) { + // Tokenize.. + SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - // Check for redundant code.. - CheckUninitVar checkuninitvar(&tokenizer, &settings, this); - (checkuninitvar.valueFlowUninit)(); + CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); + + // Check code.. + std::list fileInfo; + Check& c = getCheck(); + fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); + c.analyseWholeProgram(*ctu, fileInfo, settings, *this); // TODO: check result + while (!fileInfo.empty()) { + delete fileInfo.back(); + fileInfo.pop_back(); + } + delete ctu; } -#define ctu(code) ctu_(__FILE__, __LINE__, code) void valueFlowUninitTest() { // #9735 - FN valueFlowUninit("typedef struct\n" @@ -7351,8 +7380,7 @@ class TestUninitVar : public TestFixture { "void foo() {\n" " A a;\n" " x = a.m;\n" - "}", - true); + "}"); ASSERT_EQUALS("", errout_str()); // Unknown type (C) @@ -7951,26 +7979,6 @@ class TestUninitVar : public TestFixture { ASSERT_EQUALS("", errout_str()); } - template - void ctu_(const char* file, int line, const char (&code)[size]) { - // Tokenize.. - SimpleTokenizer tokenizer(settings, *this); - ASSERT_LOC(tokenizer.tokenize(code), file, line); - - CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); - - // Check code.. - std::list fileInfo; - Check& c = getCheck(); - fileInfo.push_back(c.getFileInfo(tokenizer, settings, "")); - c.analyseWholeProgram(*ctu, fileInfo, settings, *this); // TODO: check result - while (!fileInfo.empty()) { - delete fileInfo.back(); - fileInfo.pop_back(); - } - delete ctu; - } - void ctuTest() { ctu("void f(int *p) {\n" " a = *p;\n" diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index b1d807654af..cf027e01d79 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -91,17 +91,21 @@ class TestUnusedFunctions : public TestFixture { struct CheckOptions { Platform::Type platform = Platform::Type::Native; - const Settings* s = nullptr; bool cpp = true; }; #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) template void check_(const char* file, int line, const char (&code)[size], const CheckOptions& options = make_default_obj()) { - const Settings settings1 = settingsBuilder(options.s ? *options.s : settings).platform(options.platform).build(); + // TODO: avoid copy + const Settings settings1 = (options.platform == Platform::Type::Native) ? settings : settingsBuilder(settings).platform(options.platform).build(); - // Tokenize.. - SimpleTokenizer tokenizer(settings1, *this, options.cpp); + check_(file, line, code, settings1, options.cpp); + } + + template + void check_(const char* file, int line, const char (&code)[size], const Settings& settings1, bool cpp = true) { + SimpleTokenizer tokenizer(settings1, *this, cpp); ASSERT_LOC(tokenizer.tokenize(code), file, line); // Check for unused functions.. @@ -694,10 +698,10 @@ class TestUnusedFunctions : public TestFixture { const Settings s = settingsBuilder(settings).library("windows.cfg").build(); - check("int WinMain() { }", dinit(CheckOptions, $.s = &s)); + check("int WinMain() { }", s); ASSERT_EQUALS("", errout_str()); - check("int _tmain() { }", dinit(CheckOptions, $.s = &s)); + check("int _tmain() { }", s); ASSERT_EQUALS("", errout_str()); } @@ -710,10 +714,10 @@ class TestUnusedFunctions : public TestFixture { const Settings s = settingsBuilder(settings).library("windows.cfg").build(); - check("int wWinMain() { }", dinit(CheckOptions, $.s = &s)); + check("int wWinMain() { }", s); ASSERT_EQUALS("", errout_str()); - check("int _tmain() { }", dinit(CheckOptions, $.s = &s)); + check("int _tmain() { }", s); ASSERT_EQUALS("", errout_str()); } @@ -726,7 +730,7 @@ class TestUnusedFunctions : public TestFixture { const Settings s = settingsBuilder(settings).library("gnu.cfg").build(); check("int _init() { }\n" - "int _fini() { }\n", dinit(CheckOptions, $.s = &s)); + "int _fini() { }\n", s); ASSERT_EQUALS("", errout_str()); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 33e5037a096..23808237fcc 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -297,8 +297,8 @@ class TestValueFlow : public TestFixture { return false; } -#define testValueOfXInconclusive(code, linenr, value) testValueOfXInconclusive_(code, linenr, value, __FILE__, __LINE__) - bool testValueOfXInconclusive_(const char code[], unsigned int linenr, int value, const char* file, int line) { +#define testValueOfXInconclusive(...) testValueOfXInconclusive_(__FILE__, __LINE__, __VA_ARGS__) + bool testValueOfXInconclusive_(const char* file, int line, const char code[], unsigned int linenr, int value) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -374,8 +374,8 @@ class TestValueFlow : public TestFixture { return false; } -#define getErrorPathForX(code, linenr) getErrorPathForX_(code, linenr, __FILE__, __LINE__) - std::string getErrorPathForX_(const char code[], unsigned int linenr, const char* file, int line) { +#define getErrorPathForX(...) getErrorPathForX_(__FILE__, __LINE__, __VA_ARGS__) + std::string getErrorPathForX_(const char* file, int line, const char code[], unsigned int linenr) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -418,7 +418,7 @@ class TestValueFlow : public TestFixture { #define testLifetimeOfX(...) testLifetimeOfX_(__FILE__, __LINE__, __VA_ARGS__) template - bool testLifetimeOfX_(const char* file, int line, const char (&code)[size], unsigned int linenr, const char value[], ValueFlow::Value::LifetimeScope lifetimeScope = ValueFlow::Value::LifetimeScope::Local) { + bool testLifetimeOfX_(const char* file, int line, const char (&code)[size], unsigned int linenr, const char value[]) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -427,7 +427,7 @@ class TestValueFlow : public TestFixture { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { if (tok->str() == "x" && tok->linenr() == linenr) { if (std::any_of(tok->values().cbegin(), tok->values().cend(), [&](const ValueFlow::Value& v) { - return v.isLifetimeValue() && v.lifetimeScope == lifetimeScope && Token::simpleMatch(v.tokvalue, value, len); + return v.isLifetimeValue() && v.lifetimeScope == ValueFlow::Value::LifetimeScope::Local && Token::simpleMatch(v.tokvalue, value, len); })) return true; } @@ -470,9 +470,9 @@ class TestValueFlow : public TestFixture { return false; } -#define testConditionalValueOfX(code, linenr, value) testConditionalValueOfX_(code, linenr, value, __FILE__, __LINE__) +#define testConditionalValueOfX(...) testConditionalValueOfX_(__FILE__, __LINE__, __VA_ARGS__) template - bool testConditionalValueOfX_(const char (&code)[size], unsigned int linenr, int value, const char* file, int line) { + bool testConditionalValueOfX_(const char* file, int line, const char (&code)[size], unsigned int linenr, int value) { // Tokenize.. SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); @@ -508,8 +508,8 @@ class TestValueFlow : public TestFixture { return tok ? tok->values() : std::list(); } - std::list tokenValues_(const char* file, int line, const char code[], const char tokstr[], ValueFlow::Value::ValueType vt, const Settings *s = nullptr) { - std::list values = tokenValues_(file, line, code, tokstr, s); + std::list tokenValues_(const char* file, int line, const char code[], const char tokstr[], ValueFlow::Value::ValueType vt) { + std::list values = tokenValues_(file, line, code, tokstr); values.remove_if([&](const ValueFlow::Value& v) { return v.valueType != vt; }); @@ -518,9 +518,9 @@ class TestValueFlow : public TestFixture { #define lifetimeValues(...) lifetimeValues_(__FILE__, __LINE__, __VA_ARGS__) template - std::vector lifetimeValues_(const char* file, int line, const char (&code)[size], const char tokstr[], const Settings *s = nullptr) { + std::vector lifetimeValues_(const char* file, int line, const char (&code)[size], const char tokstr[]) { std::vector result; - SimpleTokenizer tokenizer(s ? *s : settings, *this); + SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); const Token *tok = Token::findmatch(tokenizer.tokens(), tokstr); if (!tok) @@ -546,11 +546,9 @@ class TestValueFlow : public TestFixture { int line, const char code[], const char tokstr[], - int value, - const Settings* s = nullptr, - bool cpp = true) + int value) { - std::list values = removeImpossible(tokenValues_(file, line, code, tokstr, s, cpp)); + std::list values = removeImpossible(tokenValues_(file, line, code, tokstr)); return std::any_of(values.begin(), values.end(), [&](const ValueFlow::Value& v) { return v.isKnown() && v.isIntValue() && v.intvalue == value; }); @@ -9115,7 +9113,7 @@ class TestValueFlow : public TestFixture { ASSERT_EQUALS(1U, tokenValues(code, "v .", &s).size()); } -#define testBitfields(structBody, expectedSize) testBitfields_(__FILE__, __LINE__, structBody, expectedSize) +#define testBitfields(...) testBitfields_(__FILE__, __LINE__, __VA_ARGS__) void testBitfields_(const char *file, int line, const std::string &structBody, std::size_t expectedSize) { const Settings settingsUnix64 = settingsBuilder().platform(Platform::Type::Unix64).build(); const std::string code = "struct S { " + structBody + " }; const std::size_t size = sizeof(S);"; diff --git a/test/testvarid.cpp b/test/testvarid.cpp index d2703e31a40..6f1ea052abe 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -266,15 +266,17 @@ class TestVarID : public TestFixture { struct TokenizeOptions { bool cpp = true; - const Settings *s = nullptr; }; #define tokenize(...) tokenize_(__FILE__, __LINE__, __VA_ARGS__) template std::string tokenize_(const char* file, int line, const char (&code)[size], const TokenizeOptions& options = make_default_obj()) { - const Settings *settings1 = options.s ? options.s : &settings; + return tokenize_(file, line, code, settings, options.cpp); + } - SimpleTokenizer tokenizer(*settings1, *this, options.cpp); + template + std::string tokenize_(const char* file, int line, const char (&code)[size], const Settings& settings1, bool cpp = true) { + SimpleTokenizer tokenizer(settings1, *this, cpp); ASSERT_LOC((tokenizer.tokenize)(code), file, line); // result.. @@ -310,8 +312,8 @@ class TestVarID : public TestFixture { #define compareVaridsForVariable(...) compareVaridsForVariable_(__FILE__, __LINE__, __VA_ARGS__) template - std::string compareVaridsForVariable_(const char* file, int line, const char (&code)[size], const char varname[], bool cpp = true) { - SimpleTokenizer tokenizer(settings, *this, cpp); + std::string compareVaridsForVariable_(const char* file, int line, const char (&code)[size], const char varname[]) { + SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC((tokenizer.tokenize)(code), file, line); unsigned int varid = ~0U; @@ -2296,7 +2298,7 @@ class TestVarID : public TestFixture { "4: if ( v@2 . front ( ) . i@3 ) { }\n" "5: }\n" "6: } ;\n"; - ASSERT_EQUALS(expected, tokenize(code, dinit(TokenizeOptions, $.s = &s))); + ASSERT_EQUALS(expected, tokenize(code, s)); } { @@ -2314,7 +2316,7 @@ class TestVarID : public TestFixture { "5: std :: vector < U * > * p@2 ; p@2 = g ( ) ;\n" "6: auto t@3 ; t@3 = p@2 . front ( ) . t@4 ;\n" "7: }\n"; - ASSERT_EQUALS(expected, tokenize(code, dinit(TokenizeOptions, $.s = &s))); + ASSERT_EQUALS(expected, tokenize(code, s)); } } @@ -4460,7 +4462,7 @@ class TestVarID : public TestFixture { const char* exp = "1: int f ( double a@1 , double b@2 , double c@3 ) {\n" "2: return static_cast < int > ( std :: ceil ( std :: min ( a@1 , std :: min ( b@2 , c@3 ) ) ) ) ;\n" "3: }\n"; - ASSERT_EQUALS(exp, tokenize(code, dinit(TokenizeOptions, $.s = &s))); // don't crash + ASSERT_EQUALS(exp, tokenize(code, s)); // don't crash } void structuredBindings() {