From d79d6e60db780213414b3bdaf2eabf11ceb3f769 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 26 Feb 2022 23:48:29 +0100 Subject: [PATCH] Fix #10828 Internal error. Token::Match called with varid 0 (#3859) * Fix #10828 Internal error. Token::Match called with varid 0 * Fix test --- lib/valueflow.cpp | 42 +++++++++++++++++++++--------------------- test/testvalueflow.cpp | 13 +++++++++++++ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5d94d9ae3..1af1833bd 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6083,32 +6083,32 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings)))) break; - else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, vartok->varId())) { - if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), vartok->varId())) { - if (settings->debugwarnings) - bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); - break; - } - if (settings->debugwarnings) - bailout(tokenlist, errorLogger, tok2, "For loop variable skipping conditional scope"); - tok2 = tok2->next()->link(); - if (Token::simpleMatch(tok2, "} else {")) { - if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(2), vartok->varId())) { + else if (Token::simpleMatch(tok2, ") {")) { + if (vartok->varId() && Token::findmatch(tok2->link(), "%varid%", tok2, vartok->varId())) { + if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), vartok->varId())) { if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); break; } - - tok2 = tok2->linkAt(2); + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "For loop variable skipping conditional scope"); + tok2 = tok2->next()->link(); + if (Token::simpleMatch(tok2, "} else {")) { + if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(2), vartok->varId())) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "For loop variable bailout on conditional continue|break|return"); + break; + } + tok2 = tok2->linkAt(2); + } + } + else { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "For loop skipping {} code"); + tok2 = tok2->linkAt(1); + if (Token::simpleMatch(tok2, "} else {")) + tok2 = tok2->linkAt(2); } - } - - else if (Token::simpleMatch(tok2, ") {")) { - if (settings->debugwarnings) - bailout(tokenlist, errorLogger, tok2, "For loop skipping {} code"); - tok2 = tok2->linkAt(1); - if (Token::simpleMatch(tok2, "} else {")) - tok2 = tok2->linkAt(2); } } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 6d2621766..ea94938ea 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4171,6 +4171,19 @@ private: " }\n" "}\n"; testValueOfX(code, 0, 0); // <- don't throw + + code = "struct C {\n" // #10828 + " int& v() { return i; }\n" + " int& w() { return j; }\n" + " int i{}, j{};\n" + "};\n" + "void f() {\n" + " C c;\n" + " for (c.w() = 0; c.w() < 2; c.w()++) {\n" + " for (c.v() = 0; c.v() < 24; c.v()++) {}\n" + " }\n" + "}\n"; + testValueOfX(code, 0, 0); // <- don't throw } void valueFlowSubFunction() {