diff --git a/Makefile b/Makefile index edff57e1f335..aa170d293a9b 100644 --- a/Makefile +++ b/Makefile @@ -861,7 +861,7 @@ test/testtype.o: test/testtype.cpp lib/check.h lib/checktype.h lib/color.h lib/c test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.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/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.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/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp test/testunusedprivfunc.o: test/testunusedprivfunc.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index e87fe4dbd152..514c142520aa 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -145,7 +145,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi mFunctions[markupVarToken->str()].usedOtherFile = true; else if (markupVarToken->next()->str() == "(") { FunctionUsage &func = mFunctions[markupVarToken->str()]; - func.filename = tokenizer.list.getSourceFilePath(); + func.filename = tokenizer.list.getFiles()[markupVarToken->fileIndex()]; if (func.filename.empty() || func.filename == "+") func.usedOtherFile = true; else @@ -259,7 +259,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi if (funcname) { const auto baseName = stripTemplateParameters(funcname->str()); FunctionUsage &func = mFunctions[baseName]; - const std::string& called_from_file = tokenizer.list.getSourceFilePath(); + const std::string& called_from_file = tokenizer.list.getFiles()[funcname->fileIndex()]; if (func.filename.empty() || func.filename == "+" || func.filename != called_from_file) func.usedOtherFile = true; diff --git a/test/cli/test-other.py b/test/cli/test-other.py index 1db9aa27f4d2..f262d343b4b5 100644 --- a/test/cli/test-other.py +++ b/test/cli/test-other.py @@ -232,3 +232,28 @@ def test_internal_error(tmpdir): _, _, stderr = cppcheck(args) assert stderr == '{}:0:0: error: Bailing from out analysis: Checking file failed: converting \'1f\' to integer failed - not an integer [internalError]\n\n^\n'.format(test_file) + + +# #11483 +def test_unused_function_include(tmpdir): + test_cpp_file = os.path.join(tmpdir, 'test.cpp') + with open(test_cpp_file, 'wt') as f: + f.write(""" + #include "test.h" + """) + + test_h_file = os.path.join(tmpdir, 'test.h') + with open(test_h_file, 'wt') as f: + f.write(""" + class A { + public: + void f() {} + // cppcheck-suppress unusedFunction + void f2() {} + }; + """) + + args = ['--enable=unusedFunction', '--inline-suppr', '--template={file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]', test_cpp_file] + + _, _, stderr = cppcheck(args) + assert stderr == "{}:4:0: style: The function 'f' is never used. [unusedFunction]\n".format(test_h_file) diff --git a/test/helpers.cpp b/test/helpers.cpp index dd832e3f2eb6..2e1e42c0afc0 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -125,6 +125,7 @@ std::string PreprocessorHelper::getcode(Preprocessor &preprocessor, const std::s std::string ret; try { + // TODO: also preserve location information when #include exists - enabling that will fail since #line is treated like a regular token ret = preprocessor.getcode(tokens1, cfg, files, filedata.find("#file") != std::string::npos); } catch (const simplecpp::Output &) { ret.clear(); diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 0cccc44ccbc7..f9a07f8f7127 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -18,7 +18,9 @@ #include "checkunusedfunctions.h" #include "errortypes.h" +#include "helpers.h" #include "platform.h" +#include "preprocessor.h" #include "settings.h" #include "fixture.h" #include "tokenize.h" @@ -74,6 +76,8 @@ class TestUnusedFunctions : public TestFixture { TEST_CASE(entrypointsWin); TEST_CASE(entrypointsWinU); TEST_CASE(entrypointsUnix); + + TEST_CASE(includes); } #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) @@ -673,6 +677,22 @@ class TestUnusedFunctions : public TestFixture { "int _fini() { }\n", cppcheck::Platform::Type::Native, &s); ASSERT_EQUALS("", errout.str()); } + + // TODO: fails because the location information is not be preserved by PreprocessorHelper::getcode() + void includes() + { + // #11483 + const char inc[] = "class A {\n" + "public:\n" + " void f() {}\n" + "};"; + const char code[] = R"(#include "test.h")"; + ScopedFile header("test.h", inc); + Preprocessor preprocessor(settings, this); + const std::string processed = PreprocessorHelper::getcode(preprocessor, code, "", "test.cpp"); + check(processed.c_str()); + TODO_ASSERT_EQUALS("[test.h:3]: (style) The function 'f' is never used.\n", "[test.cpp:3]: (style) The function 'f' is never used.\n", errout.str()); + } }; REGISTER_TEST(TestUnusedFunctions)