diff --git a/Makefile b/Makefile index 567c8464b..f83144ff2 100644 --- a/Makefile +++ b/Makefile @@ -272,7 +272,6 @@ TESTOBJ = test/options.o \ test/testtoken.o \ test/testtokenize.o \ test/testtokenlist.o \ - test/testtrac.o \ test/testtype.o \ test/testuninitvar.o \ test/testunusedfunctions.o \ @@ -496,7 +495,7 @@ $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml/tinyxml2.h lib/astutils.h lib/ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/errorlogger.o $(libcppdir)/errorlogger.cpp -$(libcppdir)/exprengine.o: lib/exprengine.cpp externals/z3_version.h lib/astutils.h lib/config.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h +$(libcppdir)/exprengine.o: lib/exprengine.cpp lib/astutils.h lib/config.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/exprengine.o $(libcppdir)/exprengine.cpp $(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/astutils.h lib/config.h lib/errorlogger.h lib/forwardanalyzer.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h @@ -733,9 +732,6 @@ test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/c test/testtokenlist.o: test/testtokenlist.cpp lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testtokenlist.o test/testtokenlist.cpp -test/testtrac.o: test/testtrac.cpp lib/check.h lib/checkbool.h lib/checknullpointer.h lib/checkother.h lib/config.h lib/ctu.h lib/errorlogger.h lib/mathlib.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testtrac.o test/testtrac.cpp - test/testtype.o: test/testtype.cpp lib/check.h lib/checktype.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testtype.o test/testtype.cpp diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 3222da0e3..b4f8576a4 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -188,6 +188,14 @@ private: ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + y) < (x + 10.0); } ", "+", "+")); ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; (x + 10.0) < (y + x); } ", "+", "+")); ASSERT_EQUALS(true, isSameExpression("void f() {double y = 1e1; double z = 10.0; (x + y) < (x + z); } ", "+", "+")); + ASSERT_EQUALS(true, isSameExpression("A + A", "A", "A")); + + //https://trac.cppcheck.net/ticket/9700 + ASSERT_EQUALS(true, isSameExpression("A::B + A::B;", "::", "::")); + ASSERT_EQUALS(false, isSameExpression("A::B + A::C;", "::", "::")); + ASSERT_EQUALS(true, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::B(true); }", "new", "new")); + ASSERT_EQUALS(false, isSameExpression("A::B* get() { if(x) return new A::B(true); else return new A::C(true); }", "new", "new")); + ASSERT_EQUALS(true, true); } bool isVariableChanged(const char code[], const char startPattern[], const char endPattern[]) { diff --git a/test/testbool.cpp b/test/testbool.cpp index a1b7ec8d2..05e18942f 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -62,6 +62,8 @@ private: TEST_CASE(checkComparisonOfFuncReturningBool4); TEST_CASE(checkComparisonOfFuncReturningBool5); TEST_CASE(checkComparisonOfFuncReturningBool6); + // Integration tests.. + TEST_CASE(checkComparisonOfFuncReturningBoolIntegrationTest1); // #7798 overloaded functions TEST_CASE(checkComparisonOfBoolWithBool); @@ -746,6 +748,18 @@ private: ASSERT_EQUALS("", errout.str()); } + void checkComparisonOfFuncReturningBoolIntegrationTest1() { // #7798 + check("bool eval(double *) { return false; }\n" + "double eval(char *) { return 1.0; }\n" + "int main(int argc, char *argv[])\n" + "{\n" + " if ( eval(argv[1]) > eval(argv[2]) )\n" + " return 1;\n" + " return 0;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void checkComparisonOfBoolWithBool() { const char code[] = "void f(){\n" " int temp = 4;\n" diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index eaf0f6580..bfc77e103 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -94,6 +94,7 @@ private: TEST_CASE(nullpointer51); TEST_CASE(nullpointer52); TEST_CASE(nullpointer53); // #8005 + TEST_CASE(nullpointer54); // #9573 TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -1762,6 +1763,22 @@ private: ASSERT_EQUALS("[test.cpp:3]: (warning) Possible null pointer dereference: params\n", errout.str()); } + void nullpointer54() { + check("int foo (int **array, size_t n_array) {\n" + " size_t i;\n" + " for (i = 0; i < n_array; ++i) {\n" + " if (*array[i] == 1)\n" + " return 1;\n" + " }\n" + " return 0;\n" + "} \n" + "int bar() {\n" + " int **array = NULL; \n" + " foo (array, 0);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n" diff --git a/test/testother.cpp b/test/testother.cpp index abab6cd79..fc150fcc3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -130,6 +130,7 @@ private: TEST_CASE(duplicateBranch1); // tests extracted by http://www.viva64.com/en/b/0149/ ( Comparison between PVS-Studio and cppcheck ): Errors detected in Quake 3: Arena by PVS-Studio: Fragment 2 TEST_CASE(duplicateBranch2); // empty macro TEST_CASE(duplicateBranch3); + TEST_CASE(duplicateBranch4); TEST_CASE(duplicateExpression1); TEST_CASE(duplicateExpression2); // ticket #2730 TEST_CASE(duplicateExpression3); // ticket #3317 @@ -4101,6 +4102,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void duplicateBranch4() { + check("void* f(bool b) {\n" + " if (b) {\n" + " return new A::Y(true);\n" + " } else {\n" + " return new A::Z(true);\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void duplicateExpression1() { check("void foo(int a) {\n" " if (a == a) { }\n" diff --git a/test/testtrac.cpp b/test/testtrac.cpp deleted file mode 100644 index 7cf548494..000000000 --- a/test/testtrac.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2020 Cppcheck team. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -// This file is for integration tests for trac tickets. -// -// The intention is mostly to put tests here for false positives that -// are fixed by fixing AST/ValueFlow/SymbolDatabase/etc. The check itself -// worked as it should but there was problem with the input. -// -// These tests are typically "black box" tests and don't consider how the -// checker works internally. - -#include "checkbool.h" -#include "checknullpointer.h" -#include "checkother.h" -#include "testsuite.h" -#include "settings.h" - -class TestTrac : public TestFixture { -public: - TestTrac() : TestFixture("TestTrac") { - } - -private: - - void run() OVERRIDE { - TEST_CASE(ticket_7798); - TEST_CASE(ticket_9573); - TEST_CASE(ticket_9700); - } - - template - void check(const char code[], const char *filename = "test.cpp") { - // Clear the error buffer.. - errout.str(""); - - Settings settings; - settings.addEnabled("style"); - settings.addEnabled("warning"); - settings.addEnabled("portability"); - settings.addEnabled("performance"); - settings.standards.c = Standards::CLatest; - settings.standards.cpp = Standards::CPPLatest; - settings.inconclusive = true; - - // Tokenize.. - Tokenizer tokenizer(&settings, this); - std::istringstream istr(code); - tokenizer.tokenize(istr, filename); - - // Check.. - C c(&tokenizer, &settings, this); - c.runChecks(&tokenizer, &settings, this); - } - - void ticket_7798() { - // checkComparisonOfFuncReturningBool (overloaded functions) - check("bool eval(double *) { return false; }\n" - "double eval(char *) { return 1.0; }\n" - "int main(int argc, char *argv[])\n" - "{\n" - " if ( eval(argv[1]) > eval(argv[2]) )\n" - " return 1;\n" - " return 0;\n" - "}"); - ASSERT_EQUALS("", errout.str()); - } - - void ticket_9573() { - // nullpointer (valueflow) - check("int foo (int **array, size_t n_array) {\n" - " size_t i;\n" - " for (i = 0; i < n_array; ++i) {\n" - " if (*array[i] == 1)\n" - " return 1;\n" - " }\n" - " return 0;\n" - "} \n" - "int bar() {\n" - " int **array = NULL; \n" - " foo (array, 0);\n" - "}\n"); - ASSERT_EQUALS("", errout.str()); - } - - void ticket_9700() { - // FP: duplicateBranch - check("void* f(bool b) {\n" - " if (b) {\n" - " return new A::Y(true);\n" - " } else {\n" - " return new A::Z(true);\n" - " }\n" - "}\n"); - ASSERT_EQUALS("", errout.str()); - } -}; - -REGISTER_TEST(TestTrac)