Merge branch 'mlukow'
This commit is contained in:
commit
15f8472302
|
@ -538,7 +538,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
|
||||||
if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid))
|
if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid))
|
||||||
{
|
{
|
||||||
int n = std::atoi(tok->strAt(6));
|
int n = std::atoi(tok->strAt(6));
|
||||||
if (n >= (total_size - 1))
|
if (n >= total_size)
|
||||||
strncatUsage(tok);
|
strncatUsage(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -937,7 +937,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
if (parlevel <= 0)
|
if (parlevel <= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Token::Match(tok2, "close|fclose|closedir ( %varid% )", varid))
|
if (Token::Match(tok2, "close|pclose|fclose|closedir ( %varid% )", varid))
|
||||||
{
|
{
|
||||||
addtoken("dealloc");
|
addtoken("dealloc");
|
||||||
addtoken(";");
|
addtoken(";");
|
||||||
|
|
|
@ -811,24 +811,70 @@ void CheckOther::checkIncompleteStatement()
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// str plus char
|
// str plus char
|
||||||
|
//
|
||||||
|
// What is checked:
|
||||||
|
// string = string + "xxx" + 'x'; OK
|
||||||
|
// string = const char * + %any%; ERR
|
||||||
|
// string = 'x' + %any%; ERR
|
||||||
|
// string = char + %any%; ERR
|
||||||
|
// const char * = "xxx" + %number%; OK
|
||||||
|
//
|
||||||
|
// where:
|
||||||
|
// string - variable of type string
|
||||||
|
// const char * - variable of type const char *
|
||||||
|
// 'x' - a character literal
|
||||||
|
// "xxx" - a string literal
|
||||||
|
// %any% - anything (variable or literal)
|
||||||
|
// %number% - a number (literal or variable)
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void CheckOther::strPlusChar()
|
void CheckOther::strPlusChar()
|
||||||
{
|
{
|
||||||
bool charVars[10000] = {0};
|
char strVars[10000] = {0}; // 1 - string, 2 - const char *, 3 - number (char,int,short), 0 - other
|
||||||
|
char assignToConstChar = 0; // 1 - assigning to const char *, 2 - 'const char*'-part assigned
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
// Declaring char variable..
|
if (assignToConstChar)
|
||||||
if (Token::Match(tok, "char %var% [;=]"))
|
{
|
||||||
|
if (Token::Match(tok, "%var%"))
|
||||||
|
{
|
||||||
|
unsigned int varid = tok->varId();
|
||||||
|
|
||||||
|
if (strVars[varid] == 2)
|
||||||
|
{
|
||||||
|
assignToConstChar = 2;
|
||||||
|
}
|
||||||
|
else if (!(tok->isNumber() || (strVars[varid] == 3)))
|
||||||
|
{
|
||||||
|
strPlusChar(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, "%str%"))
|
||||||
|
{
|
||||||
|
assignToConstChar = 2;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, ";"))
|
||||||
|
{
|
||||||
|
// 'const char *'-part was not found
|
||||||
|
if (assignToConstChar != 2)
|
||||||
|
{
|
||||||
|
strPlusChar(tok);
|
||||||
|
}
|
||||||
|
assignToConstChar = 0;
|
||||||
|
}
|
||||||
|
else if (!(Token::Match(tok, "[+=]") || tok->isNumber()))
|
||||||
|
{
|
||||||
|
strPlusChar(tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, "string %var% [;=]"))
|
||||||
{
|
{
|
||||||
unsigned int varid = tok->next()->varId();
|
unsigned int varid = tok->next()->varId();
|
||||||
if (varid > 0 && varid < 10000)
|
if (varid > 0 && varid < 10000)
|
||||||
charVars[varid] = true;
|
strVars[varid] = 1;
|
||||||
}
|
}
|
||||||
|
else if (Token::Match(tok, "const char * %var% [;=]"))
|
||||||
//
|
|
||||||
else if (Token::Match(tok, "[=(] %str% + %any%"))
|
|
||||||
{
|
{
|
||||||
// char constant..
|
// char constant..
|
||||||
const char *s = tok->strAt(3);
|
const char *s = tok->strAt(3);
|
||||||
|
@ -837,8 +883,29 @@ void CheckOther::strPlusChar()
|
||||||
|
|
||||||
// char variable..
|
// char variable..
|
||||||
unsigned int varid = tok->tokAt(3)->varId();
|
unsigned int varid = tok->tokAt(3)->varId();
|
||||||
if (varid > 0 && varid < 10000 && charVars[varid])
|
if (varid > 0 && varid < 10000)
|
||||||
strPlusChar(tok->next());
|
strVars[varid] = 2;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, "char|int|short %var% [;=]"))
|
||||||
|
{
|
||||||
|
unsigned int varid = tok->next()->varId();
|
||||||
|
if (varid > 0 && varid < 10000)
|
||||||
|
strVars[varid] = 3;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, "%var% = %any% + %any%") &&
|
||||||
|
(strVars[tok->varId()] == 1))
|
||||||
|
{
|
||||||
|
// string =
|
||||||
|
unsigned int varidAny = tok->tokAt(2)->varId();
|
||||||
|
// first %any% has to be a variable of type string
|
||||||
|
if (!strVars[varidAny])
|
||||||
|
strPlusChar(tok->tokAt(3));
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok, "%var% = %any%") &&
|
||||||
|
(strVars[tok->varId()] == 2))
|
||||||
|
{
|
||||||
|
// const char * =
|
||||||
|
assignToConstChar = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(strPlusChar1); // "/usr" + '/'
|
TEST_CASE(strPlusChar1); // "/usr" + '/'
|
||||||
TEST_CASE(strPlusChar2); // "/usr" + ch
|
TEST_CASE(strPlusChar2); // "/usr" + ch
|
||||||
TEST_CASE(strPlusChar3); // ok: path + "/sub" + '/'
|
TEST_CASE(strPlusChar3); // ok : path + "/sub" + '/'; err: '/' + path + "/sub"
|
||||||
|
TEST_CASE(strPlusChar4); // ok : <const char *> + <number>
|
||||||
|
|
||||||
TEST_CASE(varScope1);
|
TEST_CASE(varScope1);
|
||||||
TEST_CASE(varScope2);
|
TEST_CASE(varScope2);
|
||||||
|
@ -423,6 +424,12 @@ private:
|
||||||
" const char *p = \"/usr\" + '/';\n"
|
" const char *p = \"/usr\" + '/';\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Unusual pointer arithmetic\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Unusual pointer arithmetic\n", errout.str());
|
||||||
|
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *p = '/' + \"/usr\";\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Unusual pointer arithmetic\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void strPlusChar2()
|
void strPlusChar2()
|
||||||
|
@ -430,10 +437,23 @@ private:
|
||||||
// Strange looking pointer arithmetic..
|
// Strange looking pointer arithmetic..
|
||||||
strPlusChar("void foo()\n"
|
strPlusChar("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char ch = '/';\n"
|
" int x = 1;\n"
|
||||||
" const char *p = \"/usr\" + ch;\n"
|
" const char *p = \"/usr\" + x;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Unusual pointer arithmetic\n", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *p = \"/usr\" + 1;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" char ch = '/';\n"
|
||||||
|
" const char *p = ch + \"/usr\";\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void strPlusChar3()
|
void strPlusChar3()
|
||||||
|
@ -445,9 +465,31 @@ private:
|
||||||
" std::string path = temp + '/' + \"sub\" + '/';\n"
|
" std::string path = temp + '/' + \"sub\" + '/';\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" std::string path = '/' + \"sub\" + '/';\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Unusual pointer arithmetic\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strPlusChar4()
|
||||||
|
{
|
||||||
|
// Strange looking pointer arithmetic..
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *p = \"abcd\" + 1;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
strPlusChar("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" char ch = 1;\n"
|
||||||
|
" const char *p = \"abcd\";\n"
|
||||||
|
" const char *s = ch + p;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void varScope(const char code[])
|
void varScope(const char code[])
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue