diff --git a/lib/astutils.cpp b/lib/astutils.cpp index da7b9e73234..eeac1bc1bae 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2986,7 +2986,7 @@ bool isVariablesChanged(const Token* start, const bool globalvar = std::any_of(vars.cbegin(), vars.cend(), [](const Variable* var) { return var->isGlobal(); }); - for (const Token* tok = start; tok != end; tok = tok->next()) { + for (const Token* tok = start; tok && tok != end; tok = tok->next()) { if (tok->varId() == 0 || varids.count(tok->varId()) == 0) { if (globalvar && Token::Match(tok, "%name% (")) // TODO: Is global variable really changed by function call? diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 511af3bbea0..96e8712759a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2295,7 +2295,9 @@ bool Variable::isUnsigned() const const Token * Variable::declEndToken() const { Token const * declEnd = typeStartToken(); - while (declEnd && !Token::Match(declEnd, "[;,)={]")) { + if (declEnd->tokAt(-1) && Token::simpleMatch(declEnd->tokAt(-2), "for (")) + declEnd = nameToken(); + while (declEnd && !Token::Match(declEnd, "[;:,)={]")) { if (declEnd->link() && Token::Match(declEnd,"(|[|<")) declEnd = declEnd->link(); declEnd = declEnd->next(); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 13547c07c7f..0e600dc8bb3 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2243,6 +2243,8 @@ struct LifetimeStore { if (!var) continue; const Token * const varDeclEndToken = var->declEndToken(); + if (!varDeclEndToken) + continue; for (const Token *tok3 = tok; tok3 && tok3 != varDeclEndToken; tok3 = tok3->previous()) { if (tok3->varId() == var->declarationId()) { update |= LifetimeStore{tok3, message, type, inconclusive} diff --git a/test/testother.cpp b/test/testother.cpp index 01f4ffbe395..e67b5f64a70 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -7820,6 +7820,17 @@ class TestOther : public TestFixture { " for (; t && t->str() == s; t = t->next());\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(std::string &out, const std::vector &list) {\n" // #13669 + " for (int i = 0, size = list.size(); i < size; i++) {\n" + " out += list[i];\n" + " if (size > 0 && i < (size - 2))\n" + " out += \",\";\n" + " else if (i == (size - 1))\n" + " out += \".\";\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void duplicateExpressionTernary() { // #6391