From 8195d65554fe9dc75b8d60449c05c1d0d00a1e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Mon, 1 Jul 2024 15:21:05 +0200 Subject: [PATCH] refs #12842 - added more Python tests for whole program analysis (#6548) --- test/cli/whole-program/odr.h | 7 ++ test/cli/whole-program/odr1.cpp | 15 +++++ test/cli/whole-program/odr2.cpp | 14 ++++ test/cli/whole-program_test.py | 116 +++++++++++++++++++++++++++++++- 4 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 test/cli/whole-program/odr.h create mode 100644 test/cli/whole-program/odr1.cpp create mode 100644 test/cli/whole-program/odr2.cpp diff --git a/test/cli/whole-program/odr.h b/test/cli/whole-program/odr.h new file mode 100644 index 00000000000..29965892446 --- /dev/null +++ b/test/cli/whole-program/odr.h @@ -0,0 +1,7 @@ +class Base { +public: + virtual void f() = 0; +}; + +extern Base *c1_create(); +extern Base *c2_create(); \ No newline at end of file diff --git a/test/cli/whole-program/odr1.cpp b/test/cli/whole-program/odr1.cpp new file mode 100644 index 00000000000..ed11b42f9b3 --- /dev/null +++ b/test/cli/whole-program/odr1.cpp @@ -0,0 +1,15 @@ +#include "odr.h" + +#include + +// cppcheck-suppress ctuOneDefinitionRuleViolation +class C : public Base +{ +public: + void f() override { std::cout << "1"; } +}; + +Base *c1_create() +{ + return new C(); +} diff --git a/test/cli/whole-program/odr2.cpp b/test/cli/whole-program/odr2.cpp new file mode 100644 index 00000000000..6a08a33351d --- /dev/null +++ b/test/cli/whole-program/odr2.cpp @@ -0,0 +1,14 @@ +#include "odr.h" + +#include + +class C : public Base +{ +public: + void f() override { std::cout << "2"; } +}; + +Base *c2_create() +{ + return new C(); +} diff --git a/test/cli/whole-program_test.py b/test/cli/whole-program_test.py index a256d3d7b28..a6565cae4d0 100644 --- a/test/cli/whole-program_test.py +++ b/test/cli/whole-program_test.py @@ -6,6 +6,9 @@ __script_dir = os.path.dirname(os.path.abspath(__file__)) # TODO: use dedicated addon +# TODO: test CheckNullPointer +# TODO: test CheckUninitVar +# TODO: test CheckBufferOverrun def __create_compile_commands(dir, entries): @@ -17,7 +20,6 @@ def __create_compile_commands(dir, entries): 'command': 'gcc -c {}'.format(f), 'file': f } - print(obj) j.append(obj) compile_commands = os.path.join(dir, 'compile_commmands.json') with open(compile_commands, 'wt') as f: @@ -85,3 +87,115 @@ def test_addon_suppress_inline_project(tmpdir): @pytest.mark.xfail(strict=True) def test_addon_suppress_inline_project_j(tmpdir): __test_addon_suppress_inline_project(tmpdir, ['-j2']) + + +def __test_suppress_inline(extra_args): + args = [ + '-q', + '--template=simple', + '--enable=information,style', + '--disable=missingInclude', # TODO: remove + '--inline-suppr', + '--error-exitcode=1', + 'whole-program/odr1.cpp', + 'whole-program/odr2.cpp' + ] + + args += extra_args + + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + lines = stderr.splitlines() + assert lines == [] + assert stdout == '' + assert ret == 0, stdout + + +def test_suppress_inline(): + __test_suppress_inline(['-j1']) + + +@pytest.mark.xfail(strict=True) +def test_suppress_inline_j(): + __test_suppress_inline(['-j2']) + + +@pytest.mark.xfail(strict=True) +def test_suppress_inline_project(tmpdir): + compile_db = __create_compile_commands(tmpdir, [ + os.path.join(__script_dir, 'whole-program', 'odr1.cpp'), + os.path.join(__script_dir, 'whole-program', 'odr2.cpp') + ]) + + args = [ + '-q', + '--template=simple', + '--enable=information,style', + '--disable=missingInclude', # TODO: remove + '--inline-suppr', + '--error-exitcode=1', + '--project={}'.format(compile_db) + ] + + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + lines = stderr.splitlines() + assert lines == [] + assert stdout == '' + assert ret == 0, stdout + + +def __test_checkclass(extra_args): + args = [ + '-q', + '--template=simple', + '--enable=information,style', + '--disable=missingInclude', # TODO: remove + '--error-exitcode=1', + 'whole-program/odr1.cpp', + 'whole-program/odr2.cpp' + ] + + args += extra_args + + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + lines = stderr.splitlines() + assert lines == [ + "whole-program{}odr1.cpp:6:1: error: The one definition rule is violated, different classes/structs have the same name 'C' [ctuOneDefinitionRuleViolation]".format(os.path.sep) + ] + assert stdout == '' + assert ret == 1, stdout + + +def test_checkclass(): + __test_checkclass(['-j1']) + + +@pytest.mark.xfail(strict=True) +def test_checkclass_j(): + __test_checkclass(['-j2']) + + +@pytest.mark.xfail(strict=True) +def test_checkclass_project(tmpdir): + odr_file_1 = os.path.join(__script_dir, 'whole-program', 'odr1.cpp') + + compile_db = __create_compile_commands(tmpdir, [ + odr_file_1, + os.path.join(__script_dir, 'whole-program', 'odr2.cpp') + ]) + + args = [ + '-q', + '--template=simple', + '--enable=information,style', + '--disable=missingInclude', # TODO: remove + '--error-exitcode=1', + '--project={}'.format(compile_db) + ] + + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) + lines = stderr.splitlines() + assert lines == [ + "{}:6:1: error: The one definition rule is violated, different classes/structs have the same name 'C' [ctuOneDefinitionRuleViolation]".format(odr_file_1) + ] + assert stdout == '' + assert ret == 1, stdout \ No newline at end of file