diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index afc4c0545..1a6b3d271 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2562,10 +2562,12 @@ void Tokenizer::setVarId() if (tokStart) { for (const Token *tok2 = tokStart->next(); tok2 != tokStart->link(); tok2 = tok2->next()) { // skip parentheses.. - if (tok2->str() == "{") - tok2 = tok2->link(); - else if (tok2->str() == "(") - tok2 = tok2->link(); + if (tok2->link()) { + if (tok2->str() == "{") + tok2 = tok2->link(); + else if (tok2->str() == "(") + tok2 = tok2->link(); + } // Found a member variable.. else if (tok2->varId() > 0) @@ -7575,9 +7577,11 @@ void Tokenizer::simplifyEnum() // are there shadow variables in the scope? std::set shadowVars; for (const Token *tok3 = tok2->next(); tok3 && tok3->str() != "}"; tok3 = tok3->next()) { - if (tok3->str() == "{") + if (tok3->str() == "{") { tok3 = tok3->link(); // skip inner scopes - else if (tok3->isName() && enumValues.find(tok3->str()) != enumValues.end()) { + if (tok3 == nullptr) + break; + } else if (tok3->isName() && enumValues.find(tok3->str()) != enumValues.end()) { const Token *prev = tok3->previous(); if ((prev->isName() && !Token::Match(prev,"return|case|throw")) || Token::Match(prev, "&|* %type% =")) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index cb841f739..1b4c5e041 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -80,6 +80,7 @@ private: TEST_CASE(garbageCode6); // #5214 TEST_CASE(garbageCode7); TEST_CASE(garbageCode8); // #5511 + TEST_CASE(garbageCode9); // #5604 TEST_CASE(simplifyFileAndLineMacro); // tokenize "return - __LINE__;" @@ -1030,8 +1031,20 @@ private: tokenizeAndStringify("foo(Args&&...) fn void = { } auto template { { e = T::error }; };\n" + "ScopedEnum1 se1; { enum class E : T { e = 0 = e ScopedEnum2 struct UnscopedEnum3 { T{ e = 4 }; };\n" + "arr[(int) E::e]; }; UnscopedEnum3 e2 = f()\n" + "{ { e = e1; T::error } int test1 ue2; g() { enum class E { e = T::error }; return E::e; } int test2 = } \n" + "namespace UnscopedEnum { template struct UnscopedEnum1 { E{ e = T::error }; }; UnscopedEnum1 { enum E : { e = 0 }; };\n" + "UnscopedEnum2 ue3; template struct UnscopedEnum3 { enum { }; }; int arr[E::e]; };\n" + "UnscopedEnum3 namespace template int f() { enum E { e }; T::error }; return (int) E(); } int test1 int g() { enum E { e = E };\n" + "E::e; } int test2 = g(); }", true), InternalError); + } + + void garbageCode9() { + ASSERT_THROW(tokenizeAndStringify("enum { e = { } } ( ) { { enum { } } } { e } ", true), InternalError); } void simplifyFileAndLineMacro() { // tokenize 'return - __LINE__' correctly