Skip to content

Commit d83b6a6

Browse files
committed
adjustments for unmatched unusedFunction inline suppressions
1 parent a70b32f commit d83b6a6

File tree

6 files changed

+108
-7
lines changed

6 files changed

+108
-7
lines changed

Diff for: cli/cppcheckexecutor.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ bool CppCheckExecutor::reportSuppressions(const Settings &settings, const Suppre
240240
suppressions.getUnmatchedLocalSuppressions(i->filename, unusedFunctionCheckEnabled), errorLogger);
241241
}
242242
}
243+
if (settings.inlineSuppressions) {
244+
// report unmatched unusedFunction suppressions
245+
err |= SuppressionList::reportUnmatchedSuppressions(
246+
suppressions.getUnmatchedInlineSuppressions(unusedFunctionCheckEnabled), errorLogger);
247+
}
248+
243249
err |= SuppressionList::reportUnmatchedSuppressions(suppressions.getUnmatchedGlobalSuppressions(unusedFunctionCheckEnabled), errorLogger);
244250
return err;
245251
}

Diff for: cli/processexecutor.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ unsigned int ProcessExecutor::check()
289289
// TODO: call analyseClangTidy()?
290290
}
291291

292+
// TODO: need to transfer inline unusedFunction suppressions
293+
// TODO: need to update suppressions states
294+
292295
pipewriter.writeEnd(std::to_string(resultOfCheck));
293296
std::exit(EXIT_SUCCESS);
294297
}

Diff for: cli/threadexecutor.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class SyncLogForwarder : public ErrorLogger
8181
class ThreadData
8282
{
8383
public:
84-
ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::list<std::pair<std::string, std::size_t>> &files, const std::list<FileSettings> &fileSettings, CppCheck::ExecuteCmdFn executeCommand)
85-
: mFiles(files), mFileSettings(fileSettings), mSettings(settings), mExecuteCommand(std::move(executeCommand)), logForwarder(threadExecutor, errorLogger)
84+
ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, SuppressionList& supprs, const std::list<std::pair<std::string, std::size_t>> &files, const std::list<FileSettings> &fileSettings, CppCheck::ExecuteCmdFn executeCommand)
85+
: mFiles(files), mFileSettings(fileSettings), mSettings(settings), mSuppressions(supprs), mExecuteCommand(std::move(executeCommand)), logForwarder(threadExecutor, errorLogger)
8686
{
8787
mItNextFile = mFiles.begin();
8888
mItNextFileSettings = mFileSettings.begin();
@@ -128,6 +128,19 @@ class ThreadData
128128
result = fileChecker.check(*file);
129129
// TODO: call analyseClangTidy()?
130130
}
131+
for (const auto& suppr : fileChecker.settings().supprs.nomsg.getSuppressions()) {
132+
// need to transfer unusedFunction suppressions because these are handled later on
133+
if (suppr.isInline && suppr.errorId == "unusedFunction") {
134+
mSuppressions.addSuppression(suppr); // TODO: check result
135+
continue;
136+
}
137+
138+
// propagate state of global suppressions
139+
if (!suppr.isLocal()) {
140+
mSuppressions.updateSuppressionState(suppr); // TODO: check result
141+
continue;
142+
}
143+
}
131144
return result;
132145
}
133146

@@ -152,6 +165,7 @@ class ThreadData
152165

153166
std::mutex mFileSync;
154167
const Settings &mSettings;
168+
SuppressionList &mSuppressions;
155169
CppCheck::ExecuteCmdFn mExecuteCommand;
156170

157171
public:
@@ -180,7 +194,7 @@ unsigned int ThreadExecutor::check()
180194
std::vector<std::future<unsigned int>> threadFutures;
181195
threadFutures.reserve(mSettings.jobs);
182196

183-
ThreadData data(*this, mErrorLogger, mSettings, mFiles, mFileSettings, mExecuteCommand);
197+
ThreadData data(*this, mErrorLogger, mSettings, mSuppressions, mFiles, mFileSettings, mExecuteCommand);
184198

185199
for (unsigned int i = 0; i < mSettings.jobs; ++i) {
186200
try {

Diff for: lib/cppcheck.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -603,8 +603,12 @@ unsigned int CppCheck::check(const FileSettings &fs)
603603
for (const auto& suppr : temp.mSettings.supprs.nomsg.getSuppressions())
604604
{
605605
// skip inline suppressions - are handled in checkFile()
606-
if (suppr.isInline)
606+
if (suppr.isInline) {
607+
// need to transfer unusedFunction suppressions because these are handled later on
608+
if (suppr.errorId == "unusedFunction")
609+
mSettings.supprs.nomsg.addSuppression(suppr); // TODO: check result
607610
continue;
611+
}
608612

609613
const bool res = mSettings.supprs.nomsg.updateSuppressionState(suppr);
610614
if (!res)
@@ -1046,13 +1050,14 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
10461050

10471051
if (mSettings.severity.isEnabled(Severity::information) || mSettings.checkConfiguration) {
10481052
// TODO: check result?
1053+
// defer reporting of unusedFunction to later
10491054
SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedInlineSuppressions(false), *this);
10501055

10511056
// In jointSuppressionReport mode, unmatched suppressions are
10521057
// collected after all files are processed
10531058
if (!mSettings.useSingleJob()) {
10541059
// TODO: check result?
1055-
SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedLocalSuppressions(filename, (bool)mUnusedFunctionsCheck)), *this);
1060+
SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedLocalSuppressions(filename, (bool)mUnusedFunctionsCheck), *this);
10561061
}
10571062
}
10581063

Diff for: test/cli/inline-suppress_test.py

+70-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ def __test_compile_commands_unused_function_suppression(tmpdir, use_j):
172172
assert ret == 0, stdout
173173

174174

175-
@pytest.mark.xfail(strict=True) # TODO: need to propagate back inline suppressions
176175
def test_compile_commands_unused_function_suppression(tmpdir):
177176
__test_compile_commands_unused_function_suppression(tmpdir, False)
178177

@@ -342,4 +341,73 @@ def test_duplicate_file(tmpdir):
342341
lines = stderr.splitlines()
343342
assert lines == []
344343
assert stdout == ''
345-
assert ret == 0, stdout
344+
assert ret == 0, stdout
345+
346+
347+
# reporting of inline unusedFunction is deferred
348+
def __test_unused_function_unmatched(tmpdir, use_j):
349+
args = [
350+
'-q',
351+
'--template=simple',
352+
'--enable=all',
353+
'--inline-suppr',
354+
'proj-inline-suppress/unusedFunctionUnmatched.cpp'
355+
]
356+
357+
if use_j:
358+
args.append('-j2')
359+
else:
360+
args.append('-j1')
361+
362+
ret, stdout, stderr = cppcheck(args, cwd=__script_dir)
363+
lines = stderr.splitlines()
364+
assert lines == [
365+
'{}unusedFunctionUnmatched.cpp:5:0: information: Unmatched suppression: uninitvar [unmatchedSuppression]'.format(__proj_inline_suppres_path),
366+
'{}unusedFunctionUnmatched.cpp:5:0: information: Unmatched suppression: unusedFunction [unmatchedSuppression]'.format(__proj_inline_suppres_path)
367+
]
368+
assert stdout == ''
369+
assert ret == 0, stdout
370+
371+
372+
def test_unused_function_unmatched(tmpdir):
373+
__test_unused_function_unmatched(tmpdir, False)
374+
375+
376+
@pytest.mark.skip # unusedFunction does not work with -j
377+
def test_unused_function_unmatched_j(tmpdir):
378+
__test_unused_function_unmatched(tmpdir, True)
379+
380+
381+
# reporting of inline unusedFunction is deferred
382+
def __test_unused_function_unmatched_build_dir(tmpdir, extra_args):
383+
args = [
384+
'-q',
385+
'--template=simple',
386+
'--cppcheck-build-dir={}'.format(tmpdir),
387+
'--enable=all',
388+
'--inline-suppr',
389+
'proj-inline-suppress/unusedFunctionUnmatched.cpp'
390+
]
391+
392+
args = args + extra_args
393+
394+
ret, stdout, stderr = cppcheck(args, cwd=__script_dir)
395+
lines = stderr.splitlines()
396+
assert lines == [
397+
'{}unusedFunctionUnmatched.cpp:5:0: information: Unmatched suppression: uninitvar [unmatchedSuppression]'.format(__proj_inline_suppres_path),
398+
'{}unusedFunctionUnmatched.cpp:5:0: information: Unmatched suppression: unusedFunction [unmatchedSuppression]'.format(__proj_inline_suppres_path)
399+
]
400+
assert stdout == ''
401+
assert ret == 0, stdout
402+
403+
404+
def test_unused_function_unmatched_build_dir(tmpdir):
405+
__test_unused_function_unmatched_build_dir(tmpdir, ['-j1'])
406+
407+
408+
def test_unused_function_unmatched_build_dir_j_thread(tmpdir):
409+
__test_unused_function_unmatched_build_dir(tmpdir, ['-j2', '--executor=thread'])
410+
411+
412+
def test_unused_function_unmatched_build_dir_j_process(tmpdir):
413+
__test_unused_function_unmatched_build_dir(tmpdir, ['-j2', '--executor=process'])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// cppcheck-suppress unusedFunction
2+
void f() {
3+
// cppcheck-suppress unusedFunction
4+
// cppcheck-suppress uninitvar
5+
}

0 commit comments

Comments
 (0)