@@ -589,12 +589,27 @@ namespace {
589589 }
590590 }
591591
592+ const auto checkForRecursion = [this ]() {
593+ if (Token::Match (mTypedefToken , " typedef %name% %name% ;" ))
594+ return ;
595+ for (const Token *tok = mTypedefToken ; tok != mEndToken ; tok = tok->next ()) {
596+ if (tok == mNameToken )
597+ continue ;
598+ if (tok->str () != mNameToken ->str ())
599+ continue ;
600+ if (Token::Match (tok->previous (), " struct|class|enum|union" ))
601+ continue ;
602+ throw InternalError (tok, " recursive typedef encountered" );
603+ }
604+ };
605+
592606 for (Token* type = start; Token::Match (type, " %name%|*|&|&&" ); type = type->next ()) {
593607 if (type != start && Token::Match (type, " %name% ;" ) && !type->isStandardType ()) {
594608 mRangeType .first = start;
595609 mRangeType .second = type;
596610 mNameToken = type;
597611 mEndToken = mNameToken ->next ();
612+ checkForRecursion ();
598613 return ;
599614 }
600615 if (type != start && Token::Match (type, " %name% [" )) {
@@ -609,6 +624,7 @@ namespace {
609624 mEndToken = end->next ();
610625 mRangeAfterVar .first = mNameToken ->next ();
611626 mRangeAfterVar .second = mEndToken ;
627+ checkForRecursion ();
612628 return ;
613629 }
614630 if (Token::Match (type->next (), " ( * const| %name% ) (" ) && Token::simpleMatch (type->linkAt (1 )->linkAt (1 ), " ) ;" )) {
@@ -618,6 +634,7 @@ namespace {
618634 mRangeType .second = mNameToken ;
619635 mRangeAfterVar .first = mNameToken ->next ();
620636 mRangeAfterVar .second = mEndToken ;
637+ checkForRecursion ();
621638 return ;
622639 }
623640 if (type != start && Token::Match (type, " %name% ( !!(" ) && Token::simpleMatch (type->linkAt (1 ), " ) ;" ) && !type->isStandardType ()) {
@@ -627,6 +644,7 @@ namespace {
627644 mRangeType .second = type;
628645 mRangeAfterVar .first = mNameToken ->next ();
629646 mRangeAfterVar .second = mEndToken ;
647+ checkForRecursion ();
630648 return ;
631649 }
632650 }
0 commit comments