diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 45fbb89678d..63d85b1de3b 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -581,6 +581,7 @@ unsigned int CppCheck::check(const FileSettings &fs) if (mSettings.clang) { temp.mSettings.includePaths.insert(temp.mSettings.includePaths.end(), fs.systemIncludePaths.cbegin(), fs.systemIncludePaths.cend()); // TODO: propagate back suppressions + // TODO: propagate back mFileInfo const unsigned int returnValue = temp.check(fs.file); if (mUnusedFunctionsCheck) mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck); @@ -590,6 +591,11 @@ unsigned int CppCheck::check(const FileSettings &fs) mSettings.supprs.nomsg.addSuppressions(temp.mSettings.supprs.nomsg.getSuppressions()); if (mUnusedFunctionsCheck) mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck); + while (!temp.mFileInfo.empty()) { + mFileInfo.push_back(temp.mFileInfo.back()); + temp.mFileInfo.pop_back(); + } + // TODO: propagate back more data? return returnValue; } @@ -1764,11 +1770,14 @@ bool CppCheck::analyseWholeProgram() CTU::maxCtuDepth = mSettings.maxCtuDepth; // Analyse the tokens CTU::FileInfo ctu; - for (const Check::FileInfo *fi : mFileInfo) { - const auto *fi2 = dynamic_cast(fi); - if (fi2) { - ctu.functionCalls.insert(ctu.functionCalls.end(), fi2->functionCalls.cbegin(), fi2->functionCalls.cend()); - ctu.nestedCalls.insert(ctu.nestedCalls.end(), fi2->nestedCalls.cbegin(), fi2->nestedCalls.cend()); + if (mSettings.useSingleJob() || !mSettings.buildDir.empty()) + { + for (const Check::FileInfo *fi : mFileInfo) { + const auto *fi2 = dynamic_cast(fi); + if (fi2) { + ctu.functionCalls.insert(ctu.functionCalls.end(), fi2->functionCalls.cbegin(), fi2->functionCalls.cend()); + ctu.nestedCalls.insert(ctu.nestedCalls.end(), fi2->nestedCalls.cbegin(), fi2->nestedCalls.cend()); + } } } diff --git a/releasenotes.txt b/releasenotes.txt index c0b6c3d5588..843e590f2ac 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -20,3 +20,4 @@ Other: - Add support for 'CLICOLOR_FORCE'/'NO_COLOR' environment variables to force/disable ANSI color output for diagnostics. - Added command-line option `--cpp-header-probe` (and `--no-cpp-header-probe`) to probe headers and extension-less files for Emacs marker (see https://trac.cppcheck.net/ticket/10692 for more details) - Add "remark comments" that can be used to generate reports with justifications for warnings +- The whole program analysis is now being executed when "--project" is being used. diff --git a/test/cli/whole-program_test.py b/test/cli/whole-program_test.py index a6565cae4d0..bea81a73921 100644 --- a/test/cli/whole-program_test.py +++ b/test/cli/whole-program_test.py @@ -119,8 +119,7 @@ def test_suppress_inline_j(): __test_suppress_inline(['-j2']) -@pytest.mark.xfail(strict=True) -def test_suppress_inline_project(tmpdir): +def __test_suppress_inline_project(tmpdir, extra_args): compile_db = __create_compile_commands(tmpdir, [ os.path.join(__script_dir, 'whole-program', 'odr1.cpp'), os.path.join(__script_dir, 'whole-program', 'odr2.cpp') @@ -136,6 +135,8 @@ def test_suppress_inline_project(tmpdir): '--project={}'.format(compile_db) ] + args += extra_args + ret, stdout, stderr = cppcheck(args, cwd=__script_dir) lines = stderr.splitlines() assert lines == [] @@ -143,6 +144,15 @@ def test_suppress_inline_project(tmpdir): assert ret == 0, stdout +def test_suppress_inline_project(tmpdir): + __test_suppress_inline_project(tmpdir, ['-j1']) + + +@pytest.mark.xfail(strict=True) +def test_suppress_inline_project_j(tmpdir): + __test_suppress_inline_project(tmpdir, ['-j2']) + + def __test_checkclass(extra_args): args = [ '-q', @@ -174,8 +184,7 @@ def test_checkclass_j(): __test_checkclass(['-j2']) -@pytest.mark.xfail(strict=True) -def test_checkclass_project(tmpdir): +def __test_checkclass_project(tmpdir, extra_args): odr_file_1 = os.path.join(__script_dir, 'whole-program', 'odr1.cpp') compile_db = __create_compile_commands(tmpdir, [ @@ -192,10 +201,21 @@ def test_checkclass_project(tmpdir): '--project={}'.format(compile_db) ] + args += extra_args + 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 + assert ret == 1, stdout + + +def test_checkclass_project(tmpdir): + __test_checkclass_project(tmpdir, ['-j1']) + + +@pytest.mark.xfail(strict=True) +def test_checkclass_project_j(tmpdir): + __test_checkclass_project(tmpdir, ['-j2']) \ No newline at end of file