Fix #594 (division by zero not detected when using atol or atof)
http://sourceforge.net/apps/trac/cppcheck/ticket/594 Simplify atol("0") into 0 (and other atol() calls also)
This commit is contained in:
parent
c6b0cfc15c
commit
241f585d34
|
@ -69,6 +69,14 @@ void Token::concatStr(std::string const& b)
|
||||||
_str.append(b.begin() + 1, b.end());
|
_str.append(b.begin() + 1, b.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Token::strValue()
|
||||||
|
{
|
||||||
|
assert(_str.length() >= 2);
|
||||||
|
assert(_str[0] == '"');
|
||||||
|
assert(_str[_str.length()-1] == '"');
|
||||||
|
return _str.substr(1, _str.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
void Token::deleteNext()
|
void Token::deleteNext()
|
||||||
{
|
{
|
||||||
Token *n = _next;
|
Token *n = _next;
|
||||||
|
|
|
@ -266,6 +266,14 @@ public:
|
||||||
**/
|
**/
|
||||||
static void createMutualLinks(Token *begin, Token *end);
|
static void createMutualLinks(Token *begin, Token *end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be called only for tokens that are strings, else
|
||||||
|
* the assert() is called. If Token is e.g. '"hello"', this will return
|
||||||
|
* 'hello' (removing the double quotes).
|
||||||
|
* @return String value
|
||||||
|
*/
|
||||||
|
std::string strValue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void next(Token *next)
|
void next(Token *next)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1479,6 +1479,9 @@ void Tokenizer::simplifyTokenList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert e.g. atol("0") into 0
|
||||||
|
simplifyMathFunctions();
|
||||||
|
|
||||||
// Remove unwanted keywords
|
// Remove unwanted keywords
|
||||||
static const char * const unwantedWords[] = { "unsigned", "unlikely", "likely" };
|
static const char * const unwantedWords[] = { "unsigned", "unlikely", "likely" };
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
@ -3696,6 +3699,44 @@ void Tokenizer::syntaxError(const Token *tok, char c)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Tokenizer::simplifyMathFunctions()
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (Token::Match(tok, "atol ( %str% )"))
|
||||||
|
{
|
||||||
|
if (!MathLib::isInt(tok->tokAt(2)->strValue()))
|
||||||
|
{
|
||||||
|
// Ignore strings which we can't convert
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok->previous() &&
|
||||||
|
Token::simpleMatch(tok->previous()->previous(), "std ::"))
|
||||||
|
{
|
||||||
|
// Delete "std ::"
|
||||||
|
tok = tok->previous()->previous();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete atol(
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteThis();
|
||||||
|
|
||||||
|
// Convert string into a number
|
||||||
|
tok->str(MathLib::toString(MathLib::toLongNumber(tok->strValue())));
|
||||||
|
|
||||||
|
// Delete remaining )
|
||||||
|
tok->deleteNext();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void Tokenizer::simplifyComma()
|
void Tokenizer::simplifyComma()
|
||||||
{
|
{
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
|
|
@ -279,6 +279,13 @@ private:
|
||||||
*/
|
*/
|
||||||
void simplifyTemplates();
|
void simplifyTemplates();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify e.g. 'atol("0")' into '0'
|
||||||
|
* @return true if modifications to token-list are done.
|
||||||
|
* false if no modifications are done.
|
||||||
|
*/
|
||||||
|
bool simplifyMathFunctions();
|
||||||
|
|
||||||
void insertTokens(Token *dest, const Token *src, unsigned int n);
|
void insertTokens(Token *dest, const Token *src, unsigned int n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -115,6 +115,8 @@ private:
|
||||||
|
|
||||||
// Syntax error
|
// Syntax error
|
||||||
TEST_CASE(argumentsWithSameName)
|
TEST_CASE(argumentsWithSameName)
|
||||||
|
|
||||||
|
TEST_CASE(simplifyAtol)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[])
|
std::string tok(const char code[])
|
||||||
|
@ -1482,6 +1484,14 @@ private:
|
||||||
ASSERT_EQUALS("void foo ( int x , y ) int x ; { }", tok(code));
|
ASSERT_EQUALS("void foo ( int x , y ) int x ; { }", tok(code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyAtol()
|
||||||
|
{
|
||||||
|
ASSERT_EQUALS("a = std :: atol ( x ) ;", tok("a = std::atol(x);"));
|
||||||
|
ASSERT_EQUALS("a = atol ( \"text\" ) ;", tok("a = atol(\"text\");"));
|
||||||
|
ASSERT_EQUALS("a = 0 ;", tok("a = std::atol(\"0\");"));
|
||||||
|
ASSERT_EQUALS("a = 10 ;", tok("a = atol(\"0xa\");"));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyTokens)
|
REGISTER_TEST(TestSimplifyTokens)
|
||||||
|
|
|
@ -35,6 +35,7 @@ private:
|
||||||
TEST_CASE(nextprevious);
|
TEST_CASE(nextprevious);
|
||||||
TEST_CASE(multiCompare);
|
TEST_CASE(multiCompare);
|
||||||
TEST_CASE(getStrLength);
|
TEST_CASE(getStrLength);
|
||||||
|
TEST_CASE(strValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nextprevious()
|
void nextprevious()
|
||||||
|
@ -96,6 +97,15 @@ private:
|
||||||
Tokenizer::deleteTokens(tok);
|
Tokenizer::deleteTokens(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strValue()
|
||||||
|
{
|
||||||
|
Token tok;
|
||||||
|
tok.str("\"\"");
|
||||||
|
ASSERT_EQUALS(std::string(""), tok.strValue());
|
||||||
|
|
||||||
|
tok.str("\"0\"");
|
||||||
|
ASSERT_EQUALS(std::string("0"), tok.strValue());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestTOKEN)
|
REGISTER_TEST(TestTOKEN)
|
||||||
|
|
Loading…
Reference in New Issue