@@ -293,35 +293,73 @@ 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+ const bool skip = std::any_of (filters.cbegin (), filters.cend (), [&s](const std::string& filter) {
322+ return matchglob (filter, s.errorId );
323+ });
324+ if (skip)
325+ continue ;
326+
327+ std::list<::ErrorMessage::FileLocation> callStack;
328+ if (!s.fileName .empty ()) {
329+ callStack.emplace_back (s.fileName , s.lineNumber , 0 );
330+ }
331+ errorLogger.reportErr (::ErrorMessage (std::move (callStack), " " , Severity::information, " Unmatched suppression: " + s.errorId , " unmatchedSuppression" , Certainty::normal));
332+ err = true ;
333+ }
334+ return err;
335+ }
336+
337+ bool CppCheckExecutor::reportUnmatchedSuppressions (const Settings &settings, const SuppressionList& suppressions, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
338+ // the two inputs may only be used exclusively
339+ assert (!(!files.empty () && !fileSettings.empty ()));
340+
341+ // bail out if there is a suppression of unmatchedSuppression which matches any file
342+ const auto suppr = suppressions.getSuppressions ();
343+ if (std::any_of (suppr.cbegin (), suppr.cend (), [](const SuppressionList::Suppression& s) {
344+ return s.errorId == " unmatchedSuppression" && (s.fileName .empty () || s.fileName == " *" ) && s.lineNumber == SuppressionList::Suppression::NO_LINE;
300345 }))
301346 return false ;
302347
303348 bool err = false ;
304- if (settings.useSingleJob ()) {
305- // the two inputs may only be used exclusively
306- assert (!(!files.empty () && !fileSettings.empty ()));
307349
308- for (auto i = files.cbegin (); i != files.cend (); ++i) {
309- err |= SuppressionList::reportUnmatchedSuppressions (
310- suppressions.getUnmatchedLocalSuppressions (*i, unusedFunctionCheckEnabled), errorLogger);
311- }
350+ for (auto i = files.cbegin (); i != files.cend (); ++i) {
351+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedLocalSuppressions (*i), errorLogger, settings.unmatchedSuppressionFilters );
352+ }
312353
313- for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
314- err |= SuppressionList::reportUnmatchedSuppressions (
315- suppressions.getUnmatchedLocalSuppressions (i->file , unusedFunctionCheckEnabled), errorLogger);
316- }
354+ for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
355+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedLocalSuppressions (i->file ), errorLogger, settings.unmatchedSuppressionFilters );
317356 }
357+
318358 if (settings.inlineSuppressions ) {
319- // report unmatched unusedFunction suppressions
320- err |= SuppressionList::reportUnmatchedSuppressions (
321- suppressions.getUnmatchedInlineSuppressions (unusedFunctionCheckEnabled), errorLogger);
359+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedInlineSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
322360 }
323361
324- err |= SuppressionList ::reportUnmatchedSuppressions (suppressions.getUnmatchedGlobalSuppressions (unusedFunctionCheckEnabled ), errorLogger);
362+ err |= ::reportUnmatchedSuppressions (suppressions.getUnmatchedGlobalSuppressions (), errorLogger, settings. unmatchedSuppressionFilters );
325363 return err;
326364}
327365
@@ -376,7 +414,7 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
376414 returnValue |= cppcheck.analyseWholeProgram (settings.buildDir , mFiles , mFileSettings , stdLogger.getCtuInfo ());
377415
378416 if (settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) {
379- const bool err = reportSuppressions (settings, supprs.nomsg , settings. checks . isEnabled (Checks::unusedFunction) , mFiles , mFileSettings , stdLogger);
417+ const bool err = reportUnmatchedSuppressions (settings, supprs.nomsg , mFiles , mFileSettings , stdLogger);
380418 if (err && returnValue == 0 )
381419 returnValue = settings.exitCode ;
382420 }
0 commit comments