3232#include < cctype> // std::isdigit, std::isalnum, etc
3333#include < cstring>
3434#include < exception>
35- #include < functional> // std::bind, std::placeholders
3635#include < sstream>
3736#include < stdexcept>
3837#include < utility>
@@ -325,14 +324,27 @@ std::string SuppressionList::addSuppressionLine(const std::string &line)
325324 }
326325}
327326
327+ SuppressionList::Suppression *SuppressionList::findSameParameters (const Suppression &suppression)
328+ {
329+ const std::vector<Suppression*> *candidates = &mNonHashSuppressions ;
330+ if (suppression.hash > 0 ) {
331+ const auto it = mHashSuppressions .find (suppression.hash );
332+ if (it == mHashSuppressions .end ())
333+ return nullptr ;
334+ candidates = &it->second ;
335+ }
336+ const auto found = std::find_if (candidates->cbegin (), candidates->cend (), [&](const Suppression *s) {
337+ return suppression.isSameParameters (*s);
338+ });
339+ return found != candidates->cend () ? *found : nullptr ;
340+ }
341+
328342std::string SuppressionList::addSuppression (SuppressionList::Suppression suppression)
329343{
330344 std::lock_guard<std::mutex> lg (mSuppressionsSync );
331345
332346 // Check if suppression is already in list
333- auto foundSuppression = std::find_if (mSuppressions .begin (), mSuppressions .end (),
334- std::bind (&Suppression::isSameParameters, &suppression, std::placeholders::_1));
335- if (foundSuppression != mSuppressions .end ()) {
347+ if (findSameParameters (suppression)) {
336348 return " suppression '" + suppression.toString () + " ' already exists" ;
337349 }
338350
@@ -356,6 +368,12 @@ std::string SuppressionList::addSuppression(SuppressionList::Suppression suppres
356368
357369 mSuppressions .push_back (std::move (suppression));
358370
371+ Suppression *const added = &mSuppressions .back ();
372+ if (added->hash > 0 )
373+ mHashSuppressions [added->hash ].push_back (added);
374+ else
375+ mNonHashSuppressions .push_back (added);
376+
359377 return " " ;
360378}
361379
@@ -374,9 +392,8 @@ bool SuppressionList::updateSuppressionState(const SuppressionList::Suppression&
374392 std::lock_guard<std::mutex> lg (mSuppressionsSync );
375393
376394 // Check if suppression is already in list
377- auto foundSuppression = std::find_if (mSuppressions .begin (), mSuppressions .end (),
378- std::bind (&Suppression::isSameParameters, &suppression, std::placeholders::_1));
379- if (foundSuppression != mSuppressions .end ()) {
395+ Suppression *const foundSuppression = findSameParameters (suppression);
396+ if (foundSuppression) {
380397 if (suppression.checked )
381398 foundSuppression->checked = true ;
382399 if (suppression.matched )
@@ -525,13 +542,21 @@ bool SuppressionList::isSuppressed(const SuppressionList::ErrorMessage &errmsg,
525542 // TODO: handle unmatchedPolyspaceSuppression?
526543 const bool unmatchedSuppression (errmsg.errorId == " unmatchedSuppression" );
527544 bool returnValue = false ;
528- for (Suppression &s : mSuppressions ) {
529- if (!global && !s.isLocal ())
530- continue ;
531- if (unmatchedSuppression && s.errorId != errmsg.errorId )
532- continue ;
533- if (s.isMatch (errmsg))
534- returnValue = true ;
545+ const auto match = [&](const std::vector<Suppression*> &suppressions) {
546+ for (Suppression *s : suppressions) {
547+ if (!global && !s->isLocal ())
548+ continue ;
549+ if (unmatchedSuppression && s->errorId != errmsg.errorId )
550+ continue ;
551+ if (s->isMatch (errmsg))
552+ returnValue = true ;
553+ }
554+ };
555+ match (mNonHashSuppressions );
556+ if (errmsg.hash != 0 ) {
557+ const auto it = mHashSuppressions .find (errmsg.hash );
558+ if (it != mHashSuppressions .end ())
559+ match (it->second );
535560 }
536561 return returnValue;
537562}
@@ -540,13 +565,21 @@ bool SuppressionList::isSuppressedExplicitly(const SuppressionList::ErrorMessage
540565{
541566 std::lock_guard<std::mutex> lg (mSuppressionsSync );
542567
543- for (Suppression &s : mSuppressions ) {
544- if (!global && !s.isLocal ())
545- continue ;
546- if (s.errorId != errmsg.errorId ) // Error id must match exactly
547- continue ;
548- if (s.isMatch (errmsg))
549- return true ;
568+ const auto match = [&](const std::vector<Suppression*> &suppressions) {
569+ return std::any_of (suppressions.cbegin (), suppressions.cend (), [&](Suppression *s) {
570+ if (!global && !s->isLocal ())
571+ return false ;
572+ if (s->errorId != errmsg.errorId ) // Error id must match exactly
573+ return false ;
574+ return s->isMatch (errmsg);
575+ });
576+ };
577+ if (match (mNonHashSuppressions ))
578+ return true ;
579+ if (errmsg.hash != 0 ) {
580+ const auto it = mHashSuppressions .find (errmsg.hash );
581+ if (it != mHashSuppressions .end ())
582+ return match (it->second );
550583 }
551584 return false ;
552585}
@@ -687,7 +720,9 @@ void SuppressionList::markUnmatchedInlineSuppressionsAsChecked(const TokenList &
687720 if (currFileIdx != tok->fileIndex () || currLineNr != tok->linenr ()) {
688721 currLineNr = tok->linenr ();
689722 currFileIdx = tok->fileIndex ();
690- for (auto &suppression : mSuppressions ) {
723+ // checked is not used for hash suppressions
724+ for (Suppression *s : mNonHashSuppressions ) {
725+ Suppression &suppression = *s;
691726 if (suppression.type == SuppressionList::Type::unique) {
692727 if (!suppression.checked && (suppression.lineNumber == currLineNr) && (suppression.fileName == tokenlist.file (tok))) {
693728 suppression.checked = true ;
0 commit comments