@@ -295,13 +295,15 @@ int CppCheckExecutor::check_wrapper(const Settings& settings, Suppressions& supp
295295}
296296
297297/* *
298- * Report unmatched suppressions
299- * @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
300- * @return true is returned if errors are reported
298+ * Get list of unmatchedSuppression errors
299+ * @param unmatched list of unmatched suppressions
300+ * @param filters a list of (globbed) IDs to filter out
301+ * @return vector of unmatchedSuppression errors
301302 */
302- static bool reportUnmatchedSuppressions (const std::list<SuppressionList::Suppression> &unmatched, ErrorLogger &errorLogger , const std::vector<std::string>& filters)
303+ static std::vector<ErrorMessage> getUnmatchedSuppressions (const std::list<SuppressionList::Suppression> &unmatched, const std::vector<std::string>& filters)
303304{
304- bool err = false ;
305+ std::vector<ErrorMessage> errors;
306+
305307 // Report unmatched suppressions
306308 for (const SuppressionList::Suppression &s : unmatched) {
307309 // check if this unmatched suppression is suppressed
@@ -325,15 +327,15 @@ static bool reportUnmatchedSuppressions(const std::list<SuppressionList::Suppres
325327 if (skip)
326328 continue ;
327329
328- std::list<:: ErrorMessage::FileLocation> callStack;
330+ std::list<ErrorMessage::FileLocation> callStack;
329331 if (!s.fileName .empty ()) {
330332 callStack.emplace_back (s.fileName , s.lineNumber , 0 );
331333 }
332334 const std::string unmatchedSuppressionId = s.isPolyspace ? " unmatchedPolyspaceSuppression" : " unmatchedSuppression" ;
333- errorLogger.reportErr (::ErrorMessage (std::move (callStack), " " , Severity::information, " Unmatched suppression: " + s.errorId , unmatchedSuppressionId, Certainty::normal));
334- err = true ;
335+ errors.emplace_back (std::move (callStack), " " , Severity::information, " Unmatched suppression: " + s.errorId , unmatchedSuppressionId, Certainty::normal);
335336 }
336- return err;
337+
338+ return errors;
337339}
338340
339341bool CppCheckExecutor::reportUnmatchedSuppressions (const Settings &settings, const SuppressionList& suppressions, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
@@ -359,21 +361,55 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con
359361 supprlist.addSuppression (std::move (s));
360362 }
361363
364+ const auto reportErrorsFn = [&](const std::string& sourcefile, std::size_t fsFileId, const std::vector<ErrorMessage>& errors) -> bool {
365+ if (errors.empty ())
366+ return false ;
367+
368+ // TODO: what if sourcefile is empty?
369+
370+ AnalyzerInformation analyzerInfo;
371+ // FIXME: this is a horrible hack
372+ // we need to "re-open" the file so we can add the unmatchedSuppression findings.
373+ // we cannot keep it open conditionally because the whole program analysis reads the XML.
374+ // re-ordering the code is also not an option because the unmatched suppression reporting needs to be run after all other checks.
375+ analyzerInfo.reopen (settings.buildDir , sourcefile, /* cfgname*/ " " , fsFileId);
376+
377+ for (const auto & errmsg : errors) {
378+ analyzerInfo.reportErr (errmsg);
379+ errorLogger.reportErr (errmsg);
380+ }
381+ return true ;
382+ };
383+
362384 bool err = false ;
363385
364386 for (auto i = files.cbegin (); i != files.cend (); ++i) {
365- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (*i), errorLogger, settings.unmatchedSuppressionFilters );
387+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (*i), settings.unmatchedSuppressionFilters );
388+ err |= reportErrorsFn (i->spath (), i->fsFileId (), errors);
366389 }
367390
368391 for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
369- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (i->file ), errorLogger, settings.unmatchedSuppressionFilters );
392+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (i->file ), settings.unmatchedSuppressionFilters );
393+ err |= reportErrorsFn (i->file .spath (), i->file .fsFileId (), errors);
370394 }
371395
372396 if (settings.inlineSuppressions ) {
373- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedInlineSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
397+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedInlineSuppressions (), settings.unmatchedSuppressionFilters );
398+ for (const auto & errmsg : errors) {
399+ std::string sourcefile;
400+ if (!errmsg.callStack .empty ())
401+ sourcefile = errmsg.callStack .cbegin ()->getfile (false ); // TODO: simplify path?
402+ err |= reportErrorsFn (sourcefile, 0 , {errmsg});
403+ }
374404 }
375405
376- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedGlobalSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
406+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedGlobalSuppressions (), settings.unmatchedSuppressionFilters );
407+ for (const auto & errmsg : errors) {
408+ std::string sourcefile;
409+ if (!errmsg.callStack .empty ())
410+ sourcefile = errmsg.callStack .cbegin ()->getfile (false ); // TODO: simplify path?
411+ err |= reportErrorsFn (sourcefile, 0 , {errmsg});
412+ }
377413 return err;
378414}
379415
@@ -426,9 +462,10 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
426462#endif
427463 }
428464
465+ // TODO: is this run again instead of using previously cached results?
429466 returnValue |= cppcheck.analyseWholeProgram (settings.buildDir , mFiles , mFileSettings , stdLogger.getCtuInfo ());
430467
431- if (settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) {
468+ if (( settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) && !supprs. nomsg . getSuppressions (). empty () ) {
432469 const bool err = reportUnmatchedSuppressions (settings, supprs.nomsg , mFiles , mFileSettings , stdLogger);
433470 if (err && returnValue == 0 )
434471 returnValue = settings.exitCode ;
0 commit comments