From 79f9f5366bb7476ab7002493828a9f5196e33fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 20 Jul 2024 17:38:37 +0200 Subject: [PATCH] adjusted message about `unusedFunction` not being active / improved testing of checks requiring `--cppcheck-build-dir` (#6573) --- cli/cmdlineparser.cpp | 9 ++-- test/cli/qml_test.py | 66 +++++++++++++-------------- test/cli/unused_function_test.py | 6 +-- test/cli/whole-program_test.py | 78 +++++++++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 40 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index ae39951d855..3db41617f63 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1411,9 +1411,12 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a else if ((def || mSettings.preprocessOnly) && !maxconfigs) mSettings.maxConfigs = 1U; - if (mSettings.checks.isEnabled(Checks::unusedFunction) && mSettings.jobs > 1 && mSettings.buildDir.empty()) { - // TODO: bail out - mLogger.printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); + if (mSettings.jobs > 1 && mSettings.buildDir.empty()) { + // TODO: bail out instead? + if (mSettings.checks.isEnabled(Checks::unusedFunction)) + mLogger.printMessage("unusedFunction check requires --cppcheck-build-dir to be active with -j."); + // TODO: enable + //mLogger.printMessage("whole program analysis requires --cppcheck-build-dir to be active with -j."); } if (!mPathNames.empty() && project.projectType != ImportProject::Type::NONE) { diff --git a/test/cli/qml_test.py b/test/cli/qml_test.py index 485ab597c4e..7e09d5360e2 100644 --- a/test/cli/qml_test.py +++ b/test/cli/qml_test.py @@ -2,6 +2,7 @@ # python3 -m pytest test-qml.py import os +import pytest from testutils import cppcheck __script_dir = os.path.dirname(os.path.abspath(__file__)) @@ -11,55 +12,54 @@ __project_dir_sep = __project_dir + os.path.sep -def test_unused_functions(): - ret, stdout, stderr = cppcheck(['-q', '--template=simple', '--library=qt', '--enable=unusedFunction', '-j1', __project_dir]) - # there are unused functions. But fillSampleData is not unused because that is referenced from main.qml +def __test_unused_functions(extra_args): + args = [ + '-q', + '--template=simple', + '--library=qt', + '--enable=unusedFunction', + __project_dir + ] + args += extra_args + ret, stdout, stderr = cppcheck(args) assert stdout.splitlines() == [] - assert stderr.splitlines() == [ - "{}samplemodel.cpp:9:0: style: The function 'rowCount' is never used. [unusedFunction]".format(__project_dir_sep), + lines = stderr.splitlines() + lines.sort() + # there are unused functions. But fillSampleData is not unused because that is referenced from main.qml + assert lines == [ "{}samplemodel.cpp:15:0: style: The function 'data' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:38:0: style: The function 'roleNames' is never used. [unusedFunction]".format(__project_dir_sep) + "{}samplemodel.cpp:38:0: style: The function 'roleNames' is never used. [unusedFunction]".format(__project_dir_sep), + "{}samplemodel.cpp:9:0: style: The function 'rowCount' is never used. [unusedFunction]".format(__project_dir_sep) ] assert ret == 0, stdout +def test_unused_functions(): + __test_unused_functions(['-j1']) + + def test_unused_functions_j(): - ret, stdout, stderr = cppcheck(['-q', '--template=simple', '--library=qt', '--enable=unusedFunction', '-j2', __project_dir]) - assert stdout.splitlines() == [ - "cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check." + args = [ + '-q', + '--template=simple', + '--library=qt', + '--enable=unusedFunction', + '-j2', + __project_dir ] + ret, stdout, stderr = cppcheck(args) + assert stdout.splitlines() == ["cppcheck: unusedFunction check requires --cppcheck-build-dir to be active with -j."] assert stderr.splitlines() == [] - assert ret == 0, stdout # TODO: abil out on this + assert ret == 0, stdout # TODO: fillSampleData is not unused +@pytest.mark.xfail(strict=True) def test_unused_functions_builddir(tmpdir): build_dir = os.path.join(tmpdir, 'b1') os.mkdir(build_dir) - ret, stdout, stderr = cppcheck(['-q', '--template=simple', '--library=qt', '--enable=unusedFunction', '--cppcheck-build-dir={}'.format(build_dir), __project_dir]) - assert stdout.splitlines() == [] - assert stderr.splitlines() == [ - "{}samplemodel.cpp:15:0: style: The function 'data' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:47:0: style: The function 'fillSampleData' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:38:0: style: The function 'roleNames' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:9:0: style: The function 'rowCount' is never used. [unusedFunction]".format(__project_dir_sep), - ] - assert ret == 0, stdout - + __test_unused_functions(['--cppcheck-build-dir={}'.format(build_dir)]) -# TODO: fillSampleData is not unused -def test_unused_functions_builddir_j(tmpdir): - build_dir = os.path.join(tmpdir, 'b1') - os.mkdir(build_dir) - ret, stdout, stderr = cppcheck(['-q', '--template=simple', '--library=qt', '--enable=unusedFunction', '-j2', '--cppcheck-build-dir={}'.format(build_dir), __project_dir]) - assert stdout.splitlines() == [] - assert stderr.splitlines() == [ - "{}samplemodel.cpp:15:0: style: The function 'data' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:47:0: style: The function 'fillSampleData' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:38:0: style: The function 'roleNames' is never used. [unusedFunction]".format(__project_dir_sep), - "{}samplemodel.cpp:9:0: style: The function 'rowCount' is never used. [unusedFunction]".format(__project_dir_sep), - ] - assert ret == 0, stdout # TODO: test with project file # TODO: test with FileSettings diff --git a/test/cli/unused_function_test.py b/test/cli/unused_function_test.py index 4aa06ade4d0..3a6efcc6b66 100644 --- a/test/cli/unused_function_test.py +++ b/test/cli/unused_function_test.py @@ -42,7 +42,7 @@ def test_unused_functions(): def test_unused_functions_j(): ret, stdout, stderr = cppcheck(['-q', '--template=simple', '--enable=unusedFunction', '--inline-suppr', '-j2', __project_dir]) assert stdout.splitlines() == [ - "cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check." + "cppcheck: unusedFunction check requires --cppcheck-build-dir to be active with -j." ] assert stderr.splitlines() == [] assert ret == 0, stdout @@ -70,7 +70,7 @@ def test_unused_functions_project_j(): '--project={}'.format(os.path.join(__project_dir, 'unusedFunction.cppcheck')), '-j2']) assert stdout.splitlines() == [ - "cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check." + "cppcheck: unusedFunction check requires --cppcheck-build-dir to be active with -j." ] assert [] == stderr.splitlines() assert ret == 0, stdout @@ -102,7 +102,7 @@ def test_unused_functions_compdb_j(tmpdir): '-j2' ]) assert stdout.splitlines() == [ - "cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check." + "cppcheck: unusedFunction check requires --cppcheck-build-dir to be active with -j." ] assert stderr.splitlines() == [] assert ret == 0, stdout diff --git a/test/cli/whole-program_test.py b/test/cli/whole-program_test.py index bea81a73921..54c1f7e93a5 100644 --- a/test/cli/whole-program_test.py +++ b/test/cli/whole-program_test.py @@ -51,11 +51,27 @@ def test_addon_suppress_inline(): __test_addon_suppress_inline(['-j1']) +# TODO: inline suppressions currently do not work with whole program analysis and addons - see #12835 +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_addon_suppress_inline_j(): __test_addon_suppress_inline(['-j2']) +def test_addon_suppress_inline_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_addon_suppress_inline(['-j1', '--cppcheck-build-dir={}'.format(build_dir)]) + + +# TODO: inline suppressions currently do not work with whole program analysis and addons - see #12835 +@pytest.mark.xfail(strict=True) +def test_addon_suppress_inline_builddir_j(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_addon_suppress_inline(['-j2', '--cppcheck-build-dir={}'.format(build_dir)]) + + def __test_addon_suppress_inline_project(tmpdir, extra_args): compile_db = __create_compile_commands(tmpdir, [ os.path.join(__script_dir, 'whole-program', 'whole1.c'), @@ -84,11 +100,27 @@ def test_addon_suppress_inline_project(tmpdir): __test_addon_suppress_inline_project(tmpdir, ['-j1']) +# TODO: inline suppressions currently do not work with whole program analysis and addons - see #12835 +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_addon_suppress_inline_project_j(tmpdir): __test_addon_suppress_inline_project(tmpdir, ['-j2']) +def test_addon_suppress_inline_project_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_addon_suppress_inline_project(tmpdir, ['-j1', '--cppcheck-build-dir={}'.format(build_dir)]) + + +# TODO: inline suppressions currently do not work with whole program analysis and addons - see #12835 +@pytest.mark.xfail(strict=True) +def test_addon_suppress_inline_project_builddir_j(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_addon_suppress_inline_project(tmpdir, ['-j2', '--cppcheck-build-dir={}'.format(build_dir)]) + + def __test_suppress_inline(extra_args): args = [ '-q', @@ -114,11 +146,27 @@ def test_suppress_inline(): __test_suppress_inline(['-j1']) +# TODO: inline suppressions do not work with whole program analysis and -j +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_suppress_inline_j(): __test_suppress_inline(['-j2']) +def test_suppress_inline_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_suppress_inline(['-j1', '--cppcheck-build-dir={}'.format(build_dir)]) + + +# TODO: inline suppressions do not work with whole program analysis and -j +@pytest.mark.xfail(strict=True) +def test_suppress_inline_builddir_j(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_suppress_inline(['-j2', '--cppcheck-build-dir={}'.format(build_dir)]) + + def __test_suppress_inline_project(tmpdir, extra_args): compile_db = __create_compile_commands(tmpdir, [ os.path.join(__script_dir, 'whole-program', 'odr1.cpp'), @@ -148,11 +196,25 @@ def test_suppress_inline_project(tmpdir): __test_suppress_inline_project(tmpdir, ['-j1']) +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_suppress_inline_project_j(tmpdir): __test_suppress_inline_project(tmpdir, ['-j2']) +def test_suppress_inline_project_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_suppress_inline_project(tmpdir, ['-j1', '--cppcheck-build-dir={}'.format(build_dir)]) + +# TODO: inline suppressions do not work with whole program analysis and -j +@pytest.mark.xfail(strict=True) +def test_suppress_inline_project_builddir_j(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_suppress_inline_project(tmpdir, ['-j2', '--cppcheck-build-dir={}'.format(build_dir)]) + + def __test_checkclass(extra_args): args = [ '-q', @@ -179,11 +241,18 @@ def test_checkclass(): __test_checkclass(['-j1']) +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_checkclass_j(): __test_checkclass(['-j2']) +def test_checkclass_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_checkclass(['--cppcheck-build-dir={}'.format(build_dir)]) + + def __test_checkclass_project(tmpdir, extra_args): odr_file_1 = os.path.join(__script_dir, 'whole-program', 'odr1.cpp') @@ -216,6 +285,13 @@ def test_checkclass_project(tmpdir): __test_checkclass_project(tmpdir, ['-j1']) +# whole program analysis requires a build dir with -j @pytest.mark.xfail(strict=True) def test_checkclass_project_j(tmpdir): - __test_checkclass_project(tmpdir, ['-j2']) \ No newline at end of file + __test_checkclass_project(tmpdir, ['-j2']) + + +def test_checkclass_project_builddir(tmpdir): + build_dir = os.path.join(tmpdir, 'b1') + os.mkdir(build_dir) + __test_checkclass_project(tmpdir, ['-j1', '--cppcheck-build-dir={}'.format(build_dir)])