diff --git a/lib/token.cpp b/lib/token.cpp index df8bcca0f..de27d35b2 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1099,13 +1099,14 @@ std::string Token::stringifyList(bool varid) const void Token::astOperand1(Token *tok) { + const Token* const root = tok; if (_astOperand1) _astOperand1->_astParent = nullptr; // goto parent operator if (tok) { while (tok->_astParent) { - if (tok->_astParent == this) // #6838 avoid hang on garbage code - throw InternalError(this, "Internal error. oken::astOperand1() recursive dependency."); + if (tok->_astParent == this || tok->_astParent == root) // #6838/#6726 avoid hang on garbage code + throw InternalError(this, "Internal error. Token::astOperand1() cyclic dependency."); tok = tok->_astParent; } tok->_astParent = this; @@ -1115,13 +1116,15 @@ void Token::astOperand1(Token *tok) void Token::astOperand2(Token *tok) { + const Token* const root = tok; if (_astOperand2) _astOperand2->_astParent = nullptr; // goto parent operator if (tok) { while (tok->_astParent) { - if (tok->_astParent == this) // #6838 avoid hang on garbage code - throw InternalError(this, "Internal error. oken::astOperand1() recursive dependency."); + //std::cout << tok << " -> " << tok->_astParent ; + if (tok->_astParent == this || tok->_astParent == root) // #6838/#6726 avoid hang on garbage code + throw InternalError(this, "Internal error. Token::astOperand2() cyclic dependency."); tok = tok->_astParent; } tok->_astParent = this; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 786020cfa..cfbf3a038 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -605,7 +605,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symbo // Variable changed in 3rd for-expression if (Token::simpleMatch(tok2->previous(), "for (")) { - if (isVariableChanged(tok2->astOperand2()->astOperand2(), tok2->link(), varid)) { + if (tok2->astOperand2() && isVariableChanged(tok2->astOperand2()->astOperand2(), tok2->link(), varid)) { varid = 0U; if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok, "variable " + var->name() + " used in loop"); diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 080b03b02..07464242a 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -138,6 +138,8 @@ private: TEST_CASE(garbageCode96); TEST_CASE(garbageCode97); TEST_CASE(garbageCode98); + TEST_CASE(garbageCode99); + TEST_CASE(garbageCode100); TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); @@ -768,6 +770,17 @@ private: "fon *tok = f);.s(Token i = d-)L;"), InternalError); } + void garbageCode99() { // #6726 + ASSERT_THROW(checkCode("{ xs :: i(:) ! ! x/5 ! !\n" + "i, :: a :: b integer, } foo2(x) :: j(:) \n" + "b type(*), d(:), a x :: end d(..), foo end\n" + "foo4 b d(..), a a x type(*), b foo2 b"), InternalError); + } + + void garbageCode100() { // #6840 + checkCode("( ) { ( i< ) } int foo ( ) { int i ; ( for ( i => 1 ) ; ) }"); + } + void garbageValueFlow() { // #6089 const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"