diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 2f3ae2e8c..08fb69c7e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -532,8 +532,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), "%varid% [ %num% ]", declarationId))) || - (declarationId == 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && (Token::Match(tok->next(), (varnames + " [ %num% ]").c_str()) || Token::Match(tok->next(), (varname[0] +" [ %num% ] . " + varname[1] + " [ %num% ]").c_str()))))) { + if ((declarationId > 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), "%varid% [", declarationId))) || + (declarationId == 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && (Token::Match(tok->next(), (varnames + " [").c_str()) || Token::Match(tok->next(), (varname[0] +" [ %num% ] . " + varname[1] + " [ %num% ]").c_str()))))) { std::vector indexes; const Token *tok2 = tok->tokAt(2 + varcount); for (; Token::Match(tok2, "[ %num% ]"); tok2 = tok2->tokAt(3)) { @@ -544,6 +544,12 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectorstrAt(4)); indexes.push_back(index); } + if (indexes.empty() && arrayInfo.num().size() == 1U && Token::simpleMatch(tok2, "[") && tok2->astOperand2()) { + const ValueFlow::Value *value = tok2->astOperand2()->getMaxValue(false); + if (value) { + indexes.push_back(value->intvalue); + } + } if (indexes.size() == arrayInfo.num().size()) { // Check if the indexes point outside the whole array.. diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index c366fc61e..a20a4349f 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -438,6 +438,14 @@ private: " str[16] = 0;\n" "}"); ASSERT_EQUALS("[test.cpp:5]: (error) Array 'str[16]' accessed at index 16, which is out of bounds.\n", errout.str()); + + check("void a(int i)\n" // valueflow + "{\n" + " char *str = new char[0x10];\n" + " str[i] = 0;\n" + "}\n" + "void b() { a(16); }"); + ASSERT_EQUALS("[test.cpp:4]: (error) Array 'str[16]' accessed at index 16, which is out of bounds.\n", errout.str()); }