diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index dd1343c16..151528942 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3586,8 +3586,10 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // then unsimplified function calls etc remain. These have the // "wrong" syntax. So this function will just fix so that the // syntax is corrected. - if (!isC()) + if (!isC()) { + validate(); // #6847 - invalid code TemplateSimplifier::cleanupAfterSimplify(list.front()); + } // Simplify pointer to standard types (C only) simplifyPointerToStandardType(); @@ -3642,13 +3644,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) elseif(); - // Simplify nameless rValue references - named ones are simplified later - for (Token* tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "&& [,)]")) { - tok->str("&"); - tok->insertToken("&"); - } - } + SimplifyNamelessRValueReferences(); + validate(); return true; @@ -10496,3 +10493,14 @@ void Tokenizer::setPodTypes() } } } + +void Tokenizer::SimplifyNamelessRValueReferences() +{ + // Simplify nameless rValue references - named ones are simplified later + for (Token* tok = list.front(); tok; tok = tok->next()) { + if (Token::Match(tok, "&& [,)]")) { + tok->str("&"); + tok->insertToken("&"); + } + } +} diff --git a/lib/tokenize.h b/lib/tokenize.h index 4614a9cbc..c793a73b1 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -118,6 +118,8 @@ public: */ bool simplifyTokenList1(const char FileName[]); + void SimplifyNamelessRValueReferences(); + /** * Most aggressive simplification of tokenlist * diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 7773852c3..4df2edfbb 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -143,6 +143,7 @@ private: TEST_CASE(garbageCode101); // #6835 TEST_CASE(garbageCode102); // #6846 TEST_CASE(garbageCode103); // #6824 + TEST_CASE(garbageCode104); // #6847 TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); @@ -809,6 +810,10 @@ private: ASSERT_THROW(checkCode("a f(r) int * r; { { int s[2]; [f(s); if () ] } }"), InternalError); } + void garbageCode104() { // #6847 + ASSERT_THROW(checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }"), InternalError); + } + void garbageValueFlow() { // #6089 const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"