@@ -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
@@ -330,10 +332,11 @@ static bool reportUnmatchedSuppressions(const std::list<SuppressionList::Suppres
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+ auto errmsg = ::ErrorMessage (std::move (callStack), " " , Severity::information, " Unmatched suppression: " + s.errorId , unmatchedSuppressionId, Certainty::normal);
336+ errors. emplace_back ( std::move (errmsg)) ;
335337 }
336- return err;
338+
339+ return errors;
337340}
338341
339342bool CppCheckExecutor::reportUnmatchedSuppressions (const Settings &settings, const SuppressionList& suppressions, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, ErrorLogger& errorLogger) {
@@ -359,21 +362,55 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con
359362 supprlist.addSuppression (std::move (s));
360363 }
361364
365+ const auto reportErrorsFn = [&](const std::string& sourcefile, std::size_t fsFileId, const std::vector<::ErrorMessage>& errors) -> bool {
366+ if (errors.empty ())
367+ return false ;
368+
369+ // TODO: what if sourcefile is empty?
370+
371+ AnalyzerInformation analyzerInfo;
372+ // FIXME: this is a horrible hack
373+ // we need to "re-open" the file so we can add the unmatchedSuppression findings.
374+ // we cannot keep it open conditionally because the whole program analysis reads the XML.
375+ // re-ordering the code is also not an option because the unmatched suppression reporting needs to be run after all other checks.
376+ analyzerInfo.reopen (settings.buildDir , sourcefile, /* cfgname*/ " " , fsFileId);
377+
378+ for (const auto & errmsg : errors) {
379+ analyzerInfo.reportErr (errmsg);
380+ errorLogger.reportErr (errmsg);
381+ }
382+ return true ;
383+ };
384+
362385 bool err = false ;
363386
364387 for (auto i = files.cbegin (); i != files.cend (); ++i) {
365- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (*i), errorLogger, settings.unmatchedSuppressionFilters );
388+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (*i), settings.unmatchedSuppressionFilters );
389+ err |= reportErrorsFn (i->spath (), i->fsFileId (), errors);
366390 }
367391
368392 for (auto i = fileSettings.cbegin (); i != fileSettings.cend (); ++i) {
369- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (i->file ), errorLogger, settings.unmatchedSuppressionFilters );
393+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedLocalSuppressions (i->file ), settings.unmatchedSuppressionFilters );
394+ err |= reportErrorsFn (i->file .spath (), i->file .fsFileId (), errors);
370395 }
371396
372397 if (settings.inlineSuppressions ) {
373- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedInlineSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
398+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedInlineSuppressions (), settings.unmatchedSuppressionFilters );
399+ for (const auto & errmsg : errors) {
400+ std::string sourcefile;
401+ if (!errmsg.callStack .empty ())
402+ sourcefile = errmsg.callStack .cbegin ()->getfile (false ); // TODO: simplify path?
403+ err |= reportErrorsFn (sourcefile, 0 , {errmsg});
404+ }
374405 }
375406
376- err |= ::reportUnmatchedSuppressions (supprlist.getUnmatchedGlobalSuppressions (), errorLogger, settings.unmatchedSuppressionFilters );
407+ const std::vector<ErrorMessage> errors = getUnmatchedSuppressions (supprlist.getUnmatchedGlobalSuppressions (), settings.unmatchedSuppressionFilters );
408+ for (const auto & errmsg : errors) {
409+ std::string sourcefile;
410+ if (!errmsg.callStack .empty ())
411+ sourcefile = errmsg.callStack .cbegin ()->getfile (false ); // TODO: simplify path?
412+ err |= reportErrorsFn (sourcefile, 0 , {errmsg});
413+ }
377414 return err;
378415}
379416
@@ -426,9 +463,10 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
426463#endif
427464 }
428465
466+ // TODO: is this run again instead of using previously cached results?
429467 returnValue |= cppcheck.analyseWholeProgram (settings.buildDir , mFiles , mFileSettings , stdLogger.getCtuInfo ());
430468
431- if (settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) {
469+ if (( settings.severity .isEnabled (Severity::information) || settings.checkConfiguration ) && !supprs. nomsg . getSuppressions (). empty () ) {
432470 const bool err = reportUnmatchedSuppressions (settings, supprs.nomsg , mFiles , mFileSettings , stdLogger);
433471 if (err && returnValue == 0 )
434472 returnValue = settings.exitCode ;
0 commit comments