Refactorization: Improved handling of preprocessor in test suite
- Set Preprocessor::macroChar to '$' once in the beginning to avoid problems when changing the order of tests - Removed Preprocessor usage from where it is not required - Fixed a TODO in testuninitvar.cpp
This commit is contained in:
parent
50ed47c725
commit
07b661ef62
|
@ -6523,15 +6523,9 @@ private:
|
||||||
// Clear the error buffer..
|
// Clear the error buffer..
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
// Preprocess...
|
|
||||||
Preprocessor preprocessor(settings, this);
|
|
||||||
std::istringstream istrpreproc(code);
|
|
||||||
std::map<std::string, std::string> actual;
|
|
||||||
preprocessor.preprocess(istrpreproc, actual, "test.c");
|
|
||||||
|
|
||||||
// Tokenize..
|
// Tokenize..
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(actual[""]);
|
std::istringstream istr(code);
|
||||||
tokenizer.tokenize(istr, "test.c");
|
tokenizer.tokenize(istr, "test.c");
|
||||||
tokenizer.simplifyTokenList2();
|
tokenizer.simplifyTokenList2();
|
||||||
|
|
||||||
|
|
|
@ -4006,8 +4006,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void duplicateBranch2() {
|
void duplicateBranch2() {
|
||||||
Preprocessor::macroChar = '$';
|
|
||||||
|
|
||||||
check("void f(int x) {\n" // #4329
|
check("void f(int x) {\n" // #4329
|
||||||
" if (x)\n"
|
" if (x)\n"
|
||||||
" $;\n"
|
" $;\n"
|
||||||
|
@ -4428,7 +4426,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void duplicateExpression5() { // #3749 - macros with same values
|
void duplicateExpression5() { // #3749 - macros with same values
|
||||||
Preprocessor::macroChar = '$';
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" if ($a == $a) { }\n"
|
" if ($a == $a) { }\n"
|
||||||
"}");
|
"}");
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
class TestPreprocessor : public TestFixture {
|
class TestPreprocessor : public TestFixture {
|
||||||
public:
|
public:
|
||||||
TestPreprocessor() : TestFixture("TestPreprocessor") {
|
TestPreprocessor() : TestFixture("TestPreprocessor") {
|
||||||
Preprocessor::macroChar = '$';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class OurPreprocessor : public Preprocessor {
|
class OurPreprocessor : public Preprocessor {
|
||||||
|
@ -4010,9 +4009,9 @@ private:
|
||||||
void macroChar() const {
|
void macroChar() const {
|
||||||
const char filedata[] = "#define X 1\nX\n";
|
const char filedata[] = "#define X 1\nX\n";
|
||||||
ASSERT_EQUALS("\n$1\n", OurPreprocessor::expandMacros(filedata,nullptr));
|
ASSERT_EQUALS("\n$1\n", OurPreprocessor::expandMacros(filedata,nullptr));
|
||||||
OurPreprocessor::macroChar = char(1);
|
Preprocessor::macroChar = char(1);
|
||||||
ASSERT_EQUALS("\n" + std::string(char(1),1U) + "1\n", OurPreprocessor::expandMacros(filedata,nullptr));
|
ASSERT_EQUALS("\n" + std::string(char(1),1U) + "1\n", OurPreprocessor::expandMacros(filedata,nullptr));
|
||||||
OurPreprocessor::macroChar = '$';
|
Preprocessor::macroChar = '$';
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateCfg() {
|
void validateCfg() {
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "testsuite.h"
|
||||||
|
#include "preprocessor.h"
|
||||||
|
#include "options.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "testsuite.h"
|
#include <ctime>
|
||||||
#include "options.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -31,6 +33,8 @@ int main(int argc, char *argv[])
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
try {
|
try {
|
||||||
#endif
|
#endif
|
||||||
|
Preprocessor::macroChar = '$'; // While macroChar is char(1) per default outside test suite, we require it to be a human-readable character here.
|
||||||
|
|
||||||
options args(argc, const_cast<const char**>(argv));
|
options args(argc, const_cast<const char**>(argv));
|
||||||
|
|
||||||
std::size_t failedTestsCount = TestFixture::runTests(args);
|
std::size_t failedTestsCount = TestFixture::runTests(args);
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "checkstring.h"
|
#include "checkstring.h"
|
||||||
#include "testsuite.h"
|
#include "testsuite.h"
|
||||||
#include "preprocessor.h"
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,31 +71,6 @@ private:
|
||||||
checkString.runSimplifiedChecks(&tokenizer, &settings, this);
|
checkString.runSimplifiedChecks(&tokenizer, &settings, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_preprocess_suppress(const char precode[]) {
|
|
||||||
// Clear the error buffer..
|
|
||||||
errout.str("");
|
|
||||||
|
|
||||||
Settings settings;
|
|
||||||
settings.addEnabled("warning");
|
|
||||||
|
|
||||||
// Preprocess file..
|
|
||||||
Preprocessor preprocessor(settings, this);
|
|
||||||
std::list<std::string> configurations;
|
|
||||||
std::string filedata;
|
|
||||||
std::istringstream fin(precode);
|
|
||||||
preprocessor.preprocess(fin, filedata, configurations, "test.cpp", settings._includePaths);
|
|
||||||
const std::string code = preprocessor.getcode(filedata, "", "test.cpp");
|
|
||||||
|
|
||||||
// Tokenize..
|
|
||||||
Tokenizer tokenizer(&settings, this);
|
|
||||||
std::istringstream istr(code);
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
|
||||||
|
|
||||||
// Check..
|
|
||||||
CheckString checkString(&tokenizer, &settings, this);
|
|
||||||
checkString.checkAlwaysTrueOrFalseStringCompare();
|
|
||||||
}
|
|
||||||
|
|
||||||
void stringLiteralWrite() {
|
void stringLiteralWrite() {
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" char *abc = \"abc\";\n"
|
" char *abc = \"abc\";\n"
|
||||||
|
@ -151,7 +125,7 @@ private:
|
||||||
" if (!memcmp(p + offset, p, 42)){}\n"
|
" if (!memcmp(p + offset, p, 42)){}\n"
|
||||||
" if (!memcmp(offset + p, p, 42)){}\n"
|
" if (!memcmp(offset + p, p, 42)){}\n"
|
||||||
" if (!memcmp(p, offset + p, 42)){}\n"
|
" if (!memcmp(p, offset + p, 42)){}\n"
|
||||||
"}\n");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// avoid false positives when the address is modified #6415
|
// avoid false positives when the address is modified #6415
|
||||||
|
@ -160,7 +134,7 @@ private:
|
||||||
" if (!memcmp(c + offset, c, 42)){}\n"
|
" if (!memcmp(c + offset, c, 42)){}\n"
|
||||||
" if (!memcmp(offset + c, c, 42)){}\n"
|
" if (!memcmp(offset + c, c, 42)){}\n"
|
||||||
" if (!memcmp(c, offset + c, 42)){}\n"
|
" if (!memcmp(c, offset + c, 42)){}\n"
|
||||||
"}\n");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// avoid false positives when the address is modified #6415
|
// avoid false positives when the address is modified #6415
|
||||||
|
@ -169,103 +143,91 @@ private:
|
||||||
" if (!memcmp(s.c_str() + offset, s.c_str(), 42)){}\n"
|
" if (!memcmp(s.c_str() + offset, s.c_str(), 42)){}\n"
|
||||||
" if (!memcmp(offset + s.c_str(), s.c_str(), 42)){}\n"
|
" if (!memcmp(offset + s.c_str(), s.c_str(), 42)){}\n"
|
||||||
" if (!memcmp(s.c_str(), offset + s.c_str(), 42)){}\n"
|
" if (!memcmp(s.c_str(), offset + s.c_str(), 42)){}\n"
|
||||||
"}\n");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main()\n"
|
||||||
"#define MACRO \"00FF00\"\n"
|
"{\n"
|
||||||
"int main()\n"
|
" if (strcmp(\"00FF00\", \"00FF00\") == 0)"
|
||||||
"{\n"
|
" {"
|
||||||
" if (strcmp(MACRO,\"00FF00\") == 0)"
|
" std::cout << \"Equal\n\""
|
||||||
" {"
|
" }"
|
||||||
" std::cout << \"Equal\n\""
|
"}");
|
||||||
" }"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
|
||||||
|
|
||||||
check_preprocess_suppress(
|
|
||||||
"int main()\n"
|
|
||||||
"{\n"
|
|
||||||
" if (stricmp(\"hotdog\",\"HOTdog\") == 0)"
|
|
||||||
" {"
|
|
||||||
" std::cout << \"Equal\n\""
|
|
||||||
" }"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main()\n"
|
||||||
"#define MACRO \"Hotdog\"\n"
|
"{\n"
|
||||||
"int main()\n"
|
" if (stricmp(\"hotdog\",\"HOTdog\") == 0)"
|
||||||
"{\n"
|
" {"
|
||||||
" if (QString::compare(\"Hamburger\", MACRO) == 0)"
|
" std::cout << \"Equal\n\""
|
||||||
" {"
|
" }"
|
||||||
" std::cout << \"Equal\n\""
|
"}");
|
||||||
" }"
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main()\n"
|
||||||
"int main()\n"
|
"{\n"
|
||||||
"{\n"
|
" if (QString::compare(\"Hamburger\", \"Hotdog\") == 0)"
|
||||||
" if (QString::compare(argv[2], \"hotdog\") == 0)"
|
" {"
|
||||||
" {"
|
" std::cout << \"Equal\n\""
|
||||||
" std::cout << \"Equal\n\""
|
" }"
|
||||||
" }"
|
"}");
|
||||||
"}");
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
|
|
||||||
|
check("int main()\n"
|
||||||
|
"{\n"
|
||||||
|
" if (QString::compare(argv[2], \"hotdog\") == 0)"
|
||||||
|
" {"
|
||||||
|
" std::cout << \"Equal\n\""
|
||||||
|
" }"
|
||||||
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main()\n"
|
||||||
"int main()\n"
|
"{\n"
|
||||||
"{\n"
|
" if (strncmp(\"hotdog\",\"hotdog\", 6) == 0)"
|
||||||
" if (strncmp(\"hotdog\",\"hotdog\", 6) == 0)"
|
" {"
|
||||||
" {"
|
" std::cout << \"Equal\n\""
|
||||||
" std::cout << \"Equal\n\""
|
" }"
|
||||||
" }"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
|
|
||||||
check(
|
check("int foo(const char *buf)\n"
|
||||||
"int foo(const char *buf)\n"
|
"{\n"
|
||||||
"{\n"
|
" if (strcmp(buf, buf) == 0)"
|
||||||
" if (strcmp(buf, buf) == 0)"
|
" {"
|
||||||
" {"
|
" std::cout << \"Equal\n\""
|
||||||
" std::cout << \"Equal\n\""
|
" }"
|
||||||
" }"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
|
||||||
|
|
||||||
check(
|
check("int foo(const std::string& buf)\n"
|
||||||
"int foo(const std::string& buf)\n"
|
"{\n"
|
||||||
"{\n"
|
" if (stricmp(buf.c_str(), buf.c_str()) == 0)"
|
||||||
" if (stricmp(buf.c_str(), buf.c_str()) == 0)"
|
" {"
|
||||||
" {"
|
" std::cout << \"Equal\n\""
|
||||||
" std::cout << \"Equal\n\""
|
" }"
|
||||||
" }"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of identical string variables.\n", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main() {\n"
|
||||||
"int main() {\n"
|
" if (\"str\" == \"str\") {\n"
|
||||||
" if (\"str\" == \"str\") {\n"
|
" std::cout << \"Equal\n\"\n"
|
||||||
" std::cout << \"Equal\n\"\n"
|
" }\n"
|
||||||
" }\n"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main() {\n"
|
||||||
"int main() {\n"
|
" if (\"str\" != \"str\") {\n"
|
||||||
" if (\"str\" != \"str\") {\n"
|
" std::cout << \"Equal\n\"\n"
|
||||||
" std::cout << \"Equal\n\"\n"
|
" }\n"
|
||||||
" }\n"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) Unnecessary comparison of static strings.\n", errout.str());
|
||||||
|
|
||||||
check_preprocess_suppress(
|
check("int main() {\n"
|
||||||
"int main() {\n"
|
" if (a+\"str\" != \"str\"+b) {\n"
|
||||||
" if (a+\"str\" != \"str\"+b) {\n"
|
" std::cout << \"Equal\n\"\n"
|
||||||
" std::cout << \"Equal\n\"\n"
|
" }\n"
|
||||||
" }\n"
|
"}");
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1989,8 +1989,7 @@ private:
|
||||||
TODO_ASSERT_EQUALS("", "[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
TODO_ASSERT_EQUALS("", "[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" #define w(x) ({ x z; (x*)z; })\n" // TODO: Preprocessor?
|
" int *n = ({ typeof(*n) z; (typeof(*n)*)z; })\n"
|
||||||
" int *n = w(typeof(*n));\n"
|
|
||||||
"}", "test.cpp", false);
|
"}", "test.cpp", false);
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue