Fixed #2529 (False positive: array 'req[3]' index 4 out of bounds)

This commit is contained in:
Daniel Marjamäki 2011-02-01 21:46:07 +01:00
parent 3330981a23
commit defeded4b5
3 changed files with 44 additions and 4 deletions

View File

@ -1911,6 +1911,8 @@ void CheckOther::functionVariableUsage()
variables.use(tok->next()->varId()); // use = read + write variables.use(tok->next()->varId()); // use = read + write
else if (Token::Match(tok, "[;{}] %var% >>")) else if (Token::Match(tok, "[;{}] %var% >>"))
variables.use(tok->next()->varId()); // use = read + write variables.use(tok->next()->varId()); // use = read + write
else if (Token::Match(tok, "[{,] %var% [,}]"))
variables.read(tok->next()->varId());
// function parameter // function parameter
else if (Token::Match(tok, "[(,] %var% [")) else if (Token::Match(tok, "[(,] %var% ["))

View File

@ -2555,11 +2555,13 @@ void Tokenizer::arraySize()
const Token *tok2 = tok->tokAt(5); const Token *tok2 = tok->tokAt(5);
while (Token::Match(tok2, "%any% ,")) while (Token::Match(tok2, "%any% ,"))
{ {
if (tok2->isName())
break;
sz++; sz++;
tok2 = tok2->tokAt(2); tok2 = tok2->tokAt(2);
} }
if (Token::Match(tok2, "%any% } ;")) if (!tok2->isName() && Token::Match(tok2, "%any% } ;"))
tok->next()->insertToken(MathLib::toString<unsigned int>(sz)); tok->next()->insertToken(MathLib::toString<unsigned int>(sz));
} }
@ -4431,7 +4433,8 @@ void Tokenizer::removeRedundantAssignment()
} }
else if (tok2->varId() && else if (tok2->varId() &&
!Token::Match(tok2->previous(), "[;{}] %var% = %var% ;") && !Token::Match(tok2->previous(), "[;{}] %var% = %var% ;") &&
!Token::Match(tok2->previous(), "[;{}] %var% = %num% ;")) !Token::Match(tok2->previous(), "[;{}] %var% = %num% ;") &&
!(Token::Match(tok2->previous(), "[;{}] %var% = %any% ;") && tok2->strAt(2)[0] == '\''))
{ {
localvars.erase(tok2->varId()); localvars.erase(tok2->varId());
} }
@ -6318,6 +6321,7 @@ bool Tokenizer::simplifyKnownVariables()
else if (tok2->previous()->str() != "*" && else if (tok2->previous()->str() != "*" &&
(Token::Match(tok2, "%var% = %num% ;") || (Token::Match(tok2, "%var% = %num% ;") ||
Token::Match(tok2, "%var% = %str% ;") || Token::Match(tok2, "%var% = %str% ;") ||
(Token::Match(tok2, "%var% = %any% ;") && tok2->strAt(2)[0] == '\'') ||
Token::Match(tok2, "%var% [ ] = %str% ;") || Token::Match(tok2, "%var% [ ] = %str% ;") ||
Token::Match(tok2, "%var% [ %num% ] = %str% ;") || Token::Match(tok2, "%var% [ %num% ] = %str% ;") ||
Token::Match(tok2, "%var% = %bool% ;") || Token::Match(tok2, "%var% = %bool% ;") ||
@ -6706,6 +6710,28 @@ bool Tokenizer::simplifyKnownVariables()
ret = true; ret = true;
} }
if (Token::simpleMatch(tok3, "= {"))
{
unsigned int indentlevel4 = 0;
for (const Token *tok4 = tok3; tok4; tok4 = tok4->next())
{
if (tok4->str() == "{")
++indentlevel4;
else if (tok4->str() == "}")
{
if (indentlevel4 <= 1)
break;
--indentlevel4;
}
if (Token::Match(tok4, "{|, %varid% ,|}", varid))
{
tok4->next()->str(value);
tok4->next()->varId(valueVarId);
ret = true;
}
}
}
// Using the variable in for-condition.. // Using the variable in for-condition..
if (Token::simpleMatch(tok3, "for (")) if (Token::simpleMatch(tok3, "for ("))
{ {

View File

@ -126,6 +126,7 @@ private:
TEST_CASE(simplifyKnownVariables37); // ticket #2398 - false positive caused by no simplification in for loop TEST_CASE(simplifyKnownVariables37); // ticket #2398 - false positive caused by no simplification in for loop
TEST_CASE(simplifyKnownVariables38); // ticket #2399 - simplify conditions TEST_CASE(simplifyKnownVariables38); // ticket #2399 - simplify conditions
TEST_CASE(simplifyKnownVariables39); TEST_CASE(simplifyKnownVariables39);
TEST_CASE(simplifyKnownVariables40);
TEST_CASE(simplifyKnownVariablesBailOutAssign); TEST_CASE(simplifyKnownVariablesBailOutAssign);
TEST_CASE(simplifyKnownVariablesBailOutFor1); TEST_CASE(simplifyKnownVariablesBailOutFor1);
TEST_CASE(simplifyKnownVariablesBailOutFor2); TEST_CASE(simplifyKnownVariablesBailOutFor2);
@ -2046,6 +2047,16 @@ private:
} }
} }
void simplifyKnownVariables40()
{
const char code[] = "void f() {\n"
" char c1 = 'a';\n"
" char c2 = { c1 };\n"
"}";
ASSERT_EQUALS("void f ( ) {\n;\nchar c2 ; c2 = { 'a' } ;\n}", tokenizeAndStringify(code, true));
}
void simplifyKnownVariablesBailOutAssign() void simplifyKnownVariablesBailOutAssign()
{ {
const char code[] = "int foo() {\n" const char code[] = "int foo() {\n"
@ -4669,6 +4680,7 @@ private:
void arraySize() void arraySize()
{ {
ASSERT_EQUALS("; int a[3]={1,2,3};", arraySize_(";int a[]={1,2,3};")); ASSERT_EQUALS("; int a[3]={1,2,3};", arraySize_(";int a[]={1,2,3};"));
ASSERT_EQUALS("; int a[]={ ABC,2,3};", arraySize_(";int a[]={ABC,2,3};"));
} }
std::string labels_(const std::string &code) std::string labels_(const std::string &code)