@@ -293,35 +293,79 @@ int CppCheckExecutor::check_wrapper(const Settings& settings, Suppressions& supp
293293 return check_internal (settings, supprs);
294294}
295295
296- bool CppCheckExecutor::reportSuppressions (const Settings &settings, const SuppressionList& suppressions, bool unusedFunctionCheckEnabled, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
297- const auto & suppr = suppressions.getSuppressions ();
298- if (std::any_of (suppr.begin (), suppr.end (), [](const SuppressionList::Suppression& s) {
299- return s.errorId == " unmatchedSuppression" && s.fileName .empty () && s.lineNumber == SuppressionList::Suppression::NO_LINE;
296+ /* *
297+ * Report unmatched suppressions
298+ * @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
299+ * @return true is returned if errors are reported
300+ */
301+ static bool reportUnmatchedSuppressions (const std::list<SuppressionList::Suppression> &unmatched, ErrorLogger &errorLogger, const std::vector<std::string>& filters)
302+ {
303+ bool err = false ;
304+ // Report unmatched suppressions
305+ for (const SuppressionList::Suppression &s : unmatched) {
306+ // check if this unmatched suppression is suppressed
307+ bool suppressed = false ;
308+ for (const SuppressionList::Suppression &s2 : unmatched) {
309+ if (s2.errorId == " unmatchedSuppression" ) {
310+ if ((s2.fileName .empty () || s2.fileName == " *" || s2.fileName == s.fileName ) &&
311+ (s2.lineNumber == SuppressionList::Suppression::NO_LINE || s2.lineNumber == s.lineNumber )) {
312+ suppressed = true ;
313+ break ;
314+ }
315+ }
316+ }
317+
318+ if (suppressed)
319+ continue ;
320+
321+ bool skip = false ;
322+ for (const auto & filter : filters)
323+ {
324+ if (matchglob (filter, s.errorId ))
325+ {
326+ skip = true ;
327+ break ;
328+ }
329+ }
330+ if (skip)
331+ continue ;
332+
333+ std::list<::ErrorMessage::FileLocation> callStack;
334+ if (!s.fileName .empty ()) {
335+ callStack.emplace_back (s.fileName , s.lineNumber , 0 );
336+ }
337+ errorLogger.reportErr (::ErrorMessage (std::move (callStack), " " , Severity::information, " Unmatched suppression: " + s.errorId , " unmatchedSuppression" , Certainty::normal));
338+ err = true ;
339+ }
340+ return err;
341+ }
342+
343+ bool CppCheckExecutor::reportUnmatchedSuppressions (const Settings &settings, const SuppressionList& suppressions, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
344+ // the two inputs may only be used exclusively
345+ assert (!(!files.empty () && !fileSettings.empty ()));
346+
347+ // bail out if there is a suppression of unmatchedSuppression which matches any file
348+ const auto suppr = suppressions.getSuppressions ();
349+ if (std::any_of (suppr.cbegin (), suppr.cend (), [](const SuppressionList::Suppression& s) {
350+ return s.errorId == " unmatchedSuppression" && (s.fileName .empty () || s.fileName == " *" ) && s.lineNumber == SuppressionList::Suppression::NO_LINE;
300351 }))
301352 return false ;
302353
303354 bool err = false ;
304- if (settings.useSingleJob ()) {
305- // the two inputs may only be used exclusively
306- assert (!(!files.empty () && !fileSettings.empty ()));
307355
308- for (auto i = files.cbegin (); i != files.cend (); ++i) {
309- err |= SuppressionList::reportUnmatchedSuppressions (
310- suppressions.getUnmatchedLocalSuppressions (*i, unusedFunctionCheckEnabled), errorLogger);
311- }
356+ for (auto i = files.cbegin (); i != files.cend (); ++i) {
357+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedLocalSuppressions (*i), errorLogger, settings.unmatchedSuppressionFilters );
358+ }
312359
313- for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
314- err |= SuppressionList::reportUnmatchedSuppressions (
315- suppressions.getUnmatchedLocalSuppressions (i->file , unusedFunctionCheckEnabled), errorLogger);
316- }
360+ for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
361+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedLocalSuppressions (i->file ), errorLogger, settings.unmatchedSuppressionFilters );
317362 }
363+
318364 if (settings.inlineSuppressions ) {
319- // report unmatched unusedFunction suppressions
320- err |= SuppressionList::reportUnmatchedSuppressions (
321- suppressions.getUnmatchedInlineSuppressions (unusedFunctionCheckEnabled), errorLogger);
365+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedInlineSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
322366 }
323367
324- err |= SuppressionList ::reportUnmatchedSuppressions (suppressions.getUnmatchedGlobalSuppressions (unusedFunctionCheckEnabled ), errorLogger);
368+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedGlobalSuppressions (), errorLogger, settings. unmatchedSuppressionFilters );
325369 return err;
326370}
327371
@@ -376,7 +420,7 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
376420 returnValue |= cppcheck.analyseWholeProgram (settings.buildDir , mFiles , mFileSettings , stdLogger.getCtuInfo ());
377421
378422 if (settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) {
379- const bool err = reportSuppressions (settings, supprs.nomsg , settings. checks . isEnabled (Checks::unusedFunction) , mFiles , mFileSettings , stdLogger);
423+ const bool err = reportUnmatchedSuppressions (settings, supprs.nomsg , mFiles , mFileSettings , stdLogger);
380424 if (err && returnValue == 0 )
381425 returnValue = settings.exitCode ;
382426 }
0 commit comments