Fixed #2385 (False positive: array index out of bounds)

This commit is contained in:
Daniel Marjamäki 2010-12-31 17:43:38 +01:00
parent b04885cd4f
commit ed6c76ce04
2 changed files with 59 additions and 26 deletions

View File

@ -186,6 +186,52 @@ private:
const std::string value;
};
/**
* bailout if variable is used inside if/else/switch block or if there is "break"
* @param tok token for "if" or "switch"
* @param varid variable id
* @return is bailout recommended?
*/
static bool bailoutIfSwitch(const Token *tok, const unsigned int varid)
{
const std::string str1(tok->str());
unsigned int indentlevel = 0;
for (; tok; tok = tok->next())
{
if (tok->str() == "{")
indentlevel++;
else if (tok->str() == "}")
{
// scan the else-block
if (indentlevel == 1 && Token::simpleMatch(tok, "} else {"))
{
--indentlevel;
continue;
}
else if (indentlevel <= 1)
{
break;
}
--indentlevel;
}
// If scanning a "if" block then bailout for "break"
else if (str1 == "if" && tok->str() == "break")
return true;
// bailout if varid is found
else if (tok->varId() == varid)
return true;
}
// No bailout stuff found => return false
return false;
}
/**
* Parse for loop initialization statement. Look for a counter variable
* \param tok [in] first token inside the parentheses
@ -407,32 +453,7 @@ void CheckBufferOverrun::parse_for_body(const Token *tok2, const ArrayInfo &arra
if (Token::Match(tok2, "if|switch"))
{
bool bailout = false;
unsigned int indentlevel3 = 0;
for (const Token *tok3 = tok2; tok3; tok3 = tok3->next())
{
if (tok3->str() == "{")
indentlevel3++;
else if (tok3->str() == "}")
{
if (indentlevel3 <= 1)
break;
--indentlevel3;
}
else if (tok3->str() == "break" && tok2->str() == "if")
{
bailout = true;
break;
}
else if (tok3->varId() == arrayInfo.varid)
{
bailout = true;
break;
}
}
// Bailout
if (bailout)
if (bailoutIfSwitch(tok2, arrayInfo.varid))
break;
}

View File

@ -1338,6 +1338,18 @@ private:
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer access out-of-bounds: a\n", errout.str());
// Ticket #2385 - No false positive
check("void f() {\n"
" int a[10];\n"
" for (int i = 0; i < 20; ++i) {\n"
" if (i<10) {\n"
" } else {\n"
" a[i-10] = 0;\n"
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}