Merge branch 'master' of https://github.com/danmar/cppcheck
This commit is contained in:
commit
3ce8aaf1ce
|
@ -30,6 +30,11 @@ class ErrorLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A class containing error data for one error.
|
* @brief A class containing error data for one error.
|
||||||
|
*
|
||||||
|
* The paths are stored with internal ("/") separators. Only when we show the
|
||||||
|
* path or copy if for user (to clipboard) we convert to native separators.
|
||||||
|
* Full path is stored instead of relative path for flexibility. It is easy
|
||||||
|
* to get the relative path from full path when needed.
|
||||||
*/
|
*/
|
||||||
class ErrorItem
|
class ErrorItem
|
||||||
{
|
{
|
||||||
|
|
|
@ -719,7 +719,7 @@ void ResultsTree::CopyPath(QStandardItem *target, bool fullPath)
|
||||||
|
|
||||||
//Replace (file) with filename
|
//Replace (file) with filename
|
||||||
QString file = data["file"].toString();
|
QString file = data["file"].toString();
|
||||||
pathStr = file;
|
pathStr = QDir::toNativeSeparators(file);
|
||||||
if (!fullPath)
|
if (!fullPath)
|
||||||
{
|
{
|
||||||
QFileInfo fi(pathStr);
|
QFileInfo fi(pathStr);
|
||||||
|
|
|
@ -2819,7 +2819,7 @@ void CheckOther::catchExceptionByValueError(const Token *tok)
|
||||||
|
|
||||||
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
|
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
|
||||||
{
|
{
|
||||||
reportError(tok, Severity::warning,
|
const std::string summary("memset() called to fill 0 bytes of \'" + varname + "\'");
|
||||||
"memsetZeroBytes", "memset() called to fill 0 bytes of \"" + varname + "\""
|
const std::string verbose(summary + ". Second and third arguments might be inverted.");
|
||||||
". Second and third arguments might be inverted.");
|
reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ static BOOL MyIsDirectory(std::string path)
|
||||||
return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY);
|
return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
#else
|
#else
|
||||||
// See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx
|
// See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx
|
||||||
return PathIsDirectory(path.c_str());
|
return PathIsDirectory(path.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -699,8 +699,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
|
||||||
processedFile = ostr.str();
|
processedFile = ostr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> systemIncludes;
|
handleIncludes(processedFile, filename, includePaths);
|
||||||
handleIncludes(processedFile, filename, includePaths, systemIncludes);
|
|
||||||
|
|
||||||
processedFile = replaceIfDefined(processedFile);
|
processedFile = replaceIfDefined(processedFile);
|
||||||
|
|
||||||
|
@ -1490,13 +1489,17 @@ static int tolowerWrapper(int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Preprocessor::handleIncludes(std::string &code,
|
void Preprocessor::handleIncludes(std::string &code, const std::string &filePath, const std::list<std::string> &includePaths)
|
||||||
const std::string &filePath,
|
|
||||||
const std::list<std::string> &includePaths,
|
|
||||||
std::set<std::string> &systemIncludes,
|
|
||||||
std::set<std::string> handledFiles)
|
|
||||||
{
|
{
|
||||||
|
std::list<std::string> paths;
|
||||||
|
std::string path;
|
||||||
|
path = filePath;
|
||||||
|
path.erase(1 + path.find_last_of("\\/"));
|
||||||
|
paths.push_back(path);
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
|
std::string::size_type endfilePos = 0;
|
||||||
|
std::set<std::string> handledFiles;
|
||||||
|
endfilePos = pos;
|
||||||
while ((pos = code.find("#include", pos)) != std::string::npos)
|
while ((pos = code.find("#include", pos)) != std::string::npos)
|
||||||
{
|
{
|
||||||
// Accept only includes that are at the start of a line
|
// Accept only includes that are at the start of a line
|
||||||
|
@ -1506,6 +1509,15 @@ void Preprocessor::handleIncludes(std::string &code,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If endfile is encountered, we have moved to a next file in our stack,
|
||||||
|
// so remove last path in our list.
|
||||||
|
while ((endfilePos = code.find("\n#endfile", endfilePos)) != std::string::npos && endfilePos < pos)
|
||||||
|
{
|
||||||
|
paths.pop_back();
|
||||||
|
endfilePos += 9; // size of #endfile
|
||||||
|
}
|
||||||
|
|
||||||
|
endfilePos = pos;
|
||||||
std::string::size_type end = code.find("\n", pos);
|
std::string::size_type end = code.find("\n", pos);
|
||||||
std::string filename = code.substr(pos, end - pos);
|
std::string filename = code.substr(pos, end - pos);
|
||||||
|
|
||||||
|
@ -1539,17 +1551,11 @@ void Preprocessor::handleIncludes(std::string &code,
|
||||||
|
|
||||||
if (headerType == UserHeader && !fileOpened)
|
if (headerType == UserHeader && !fileOpened)
|
||||||
{
|
{
|
||||||
if (filePath.find_first_of("\\/") != std::string::npos)
|
fin.open((paths.back() + filename).c_str());
|
||||||
|
if (fin.is_open())
|
||||||
{
|
{
|
||||||
std::string path(filePath);
|
filename = paths.back() + filename;
|
||||||
path.erase(1 + path.find_last_of("\\/"));
|
fileOpened = true;
|
||||||
|
|
||||||
fin.open((path + filename).c_str());
|
|
||||||
if (fin.is_open())
|
|
||||||
{
|
|
||||||
filename = path + filename;
|
|
||||||
fileOpened = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1558,8 +1564,7 @@ void Preprocessor::handleIncludes(std::string &code,
|
||||||
filename = Path::simplifyPath(filename.c_str());
|
filename = Path::simplifyPath(filename.c_str());
|
||||||
std::string tempFile = filename;
|
std::string tempFile = filename;
|
||||||
std::transform(tempFile.begin(), tempFile.end(), tempFile.begin(), tolowerWrapper);
|
std::transform(tempFile.begin(), tempFile.end(), tempFile.begin(), tolowerWrapper);
|
||||||
if (handledFiles.find(tempFile) != handledFiles.end() ||
|
if (handledFiles.find(tempFile) != handledFiles.end())
|
||||||
(headerType == SystemHeader && systemIncludes.find(tempFile) != systemIncludes.end()))
|
|
||||||
{
|
{
|
||||||
// We have processed this file already once, skip
|
// We have processed this file already once, skip
|
||||||
// it this time to avoid eternal loop.
|
// it this time to avoid eternal loop.
|
||||||
|
@ -1567,10 +1572,7 @@ void Preprocessor::handleIncludes(std::string &code,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerType == SystemHeader)
|
handledFiles.insert(tempFile);
|
||||||
systemIncludes.insert(tempFile);
|
|
||||||
else
|
|
||||||
handledFiles.insert(tempFile);
|
|
||||||
processedFile = Preprocessor::read(fin, filename, _settings);
|
processedFile = Preprocessor::read(fin, filename, _settings);
|
||||||
fin.close();
|
fin.close();
|
||||||
}
|
}
|
||||||
|
@ -1586,10 +1588,12 @@ void Preprocessor::handleIncludes(std::string &code,
|
||||||
|
|
||||||
// Remove space characters that are after or before new line character
|
// Remove space characters that are after or before new line character
|
||||||
processedFile = removeSpaceNearNL(processedFile);
|
processedFile = removeSpaceNearNL(processedFile);
|
||||||
handleIncludes(processedFile, filename, includePaths, systemIncludes, handledFiles);
|
|
||||||
processedFile = "#file \"" + filename + "\"\n" + processedFile + "\n#endfile";
|
processedFile = "#file \"" + filename + "\"\n" + processedFile + "\n#endfile";
|
||||||
code.insert(pos, processedFile);
|
code.insert(pos, processedFile);
|
||||||
pos += processedFile.size();
|
|
||||||
|
path = filename;
|
||||||
|
path.erase(1 + path.find_last_of("\\/"));
|
||||||
|
paths.push_back(path);
|
||||||
}
|
}
|
||||||
else if (!fileOpened)
|
else if (!fileOpened)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
class ErrorLogger;
|
class ErrorLogger;
|
||||||
class Settings;
|
class Settings;
|
||||||
|
@ -213,16 +212,9 @@ private:
|
||||||
* There must be a path separator at the end. Default parameter is empty list.
|
* There must be a path separator at the end. Default parameter is empty list.
|
||||||
* Note that if path from given filename is also extracted and that is used as
|
* Note that if path from given filename is also extracted and that is used as
|
||||||
* a last include path if include file was not found from earlier paths.
|
* a last include path if include file was not found from earlier paths.
|
||||||
* @param systemIncludes System includes
|
|
||||||
* @param handledFiles used in the recursive handling. Should be empty unless
|
|
||||||
* a recursive call is made.
|
|
||||||
* @return modified source code
|
* @return modified source code
|
||||||
*/
|
*/
|
||||||
void handleIncludes(std::string &code,
|
void handleIncludes(std::string &code, const std::string &filePath, const std::list<std::string> &includePaths);
|
||||||
const std::string &filePath,
|
|
||||||
const std::list<std::string> &includePaths,
|
|
||||||
std::set<std::string> &systemIncludes,
|
|
||||||
std::set<std::string> handledFiles = std::set<std::string>());
|
|
||||||
|
|
||||||
Settings *_settings;
|
Settings *_settings;
|
||||||
ErrorLogger *_errorLogger;
|
ErrorLogger *_errorLogger;
|
||||||
|
|
|
@ -1574,7 +1574,8 @@ void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::list<st
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calling member function?
|
// Calling member function?
|
||||||
else if (Token::simpleMatch(ftok, "operator = ("))
|
else if (Token::simpleMatch(ftok, "operator = (") &&
|
||||||
|
ftok->previous()->str() != "::")
|
||||||
{
|
{
|
||||||
// check if member function exists
|
// check if member function exists
|
||||||
std::list<Func>::const_iterator it;
|
std::list<Func>::const_iterator it;
|
||||||
|
|
|
@ -665,8 +665,16 @@ void Tokenizer::unsupportedTypedef(const Token *tok) const
|
||||||
|
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
const Token *tok1 = tok;
|
const Token *tok1 = tok;
|
||||||
while (tok && tok->str() != ";")
|
int level = 0;
|
||||||
|
while (tok)
|
||||||
{
|
{
|
||||||
|
if (level == 0 && tok->str() == ";")
|
||||||
|
break;
|
||||||
|
else if (tok->str() == "{")
|
||||||
|
level++;
|
||||||
|
else if (tok->str() == "}")
|
||||||
|
level--;
|
||||||
|
|
||||||
if (tok != tok1)
|
if (tok != tok1)
|
||||||
str << " ";
|
str << " ";
|
||||||
str << tok->str();
|
str << tok->str();
|
||||||
|
@ -694,10 +702,19 @@ void Tokenizer::unsupportedTypedef(const Token *tok) const
|
||||||
Token * Tokenizer::deleteInvalidTypedef(Token *typeDef)
|
Token * Tokenizer::deleteInvalidTypedef(Token *typeDef)
|
||||||
{
|
{
|
||||||
Token *tok = NULL;
|
Token *tok = NULL;
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
// remove typedef but leave ;
|
// remove typedef but leave ;
|
||||||
while (typeDef->next() && typeDef->next()->str() != ";")
|
while (typeDef->next())
|
||||||
|
{
|
||||||
|
if (level == 0 && typeDef->next()->str() == ";")
|
||||||
|
break;
|
||||||
|
else if (typeDef->next()->str() == "{")
|
||||||
|
level++;
|
||||||
|
else if (typeDef->next()->str() == "}")
|
||||||
|
level--;
|
||||||
typeDef->deleteNext();
|
typeDef->deleteNext();
|
||||||
|
}
|
||||||
|
|
||||||
if (typeDef != _tokens)
|
if (typeDef != _tokens)
|
||||||
{
|
{
|
||||||
|
@ -2029,6 +2046,22 @@ bool Tokenizer::tokenize(std::istream &code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace NULL with 0..
|
||||||
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == "NULL" || tok->str() == "'\\0'" || tok->str() == "'\\x0'")
|
||||||
|
{
|
||||||
|
tok->str("0");
|
||||||
|
}
|
||||||
|
else if (tok->isNumber() &&
|
||||||
|
MathLib::isInt(tok->str()) &&
|
||||||
|
MathLib::toLongNumber(tok->str()) == 0)
|
||||||
|
{
|
||||||
|
tok->str("0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove inline SQL (Oracle PRO*C). Ticket: #1959
|
// remove inline SQL (Oracle PRO*C). Ticket: #1959
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
|
@ -2422,6 +2455,8 @@ bool Tokenizer::tokenize(std::istream &code,
|
||||||
// Change initialisation of variable to assignment
|
// Change initialisation of variable to assignment
|
||||||
simplifyInitVar();
|
simplifyInitVar();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!preprocessorCondition)
|
if (!preprocessorCondition)
|
||||||
{
|
{
|
||||||
setVarId();
|
setVarId();
|
||||||
|
@ -3987,22 +4022,6 @@ bool Tokenizer::simplifyTokenList()
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Replace NULL with 0..
|
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
|
||||||
{
|
|
||||||
if (tok->str() == "NULL" || tok->str() == "'\\0'" || tok->str() == "'\\x0'")
|
|
||||||
{
|
|
||||||
tok->str("0");
|
|
||||||
}
|
|
||||||
else if (tok->isNumber() &&
|
|
||||||
MathLib::isInt(tok->str()) &&
|
|
||||||
MathLib::toLongNumber(tok->str()) == 0)
|
|
||||||
{
|
|
||||||
tok->str("0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// simplify references
|
// simplify references
|
||||||
simplifyReference();
|
simplifyReference();
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ sub checkfile
|
||||||
}
|
}
|
||||||
|
|
||||||
# set comment variable
|
# set comment variable
|
||||||
if ($line =~ /\/\//)
|
if (($line =~ /\/\//) || ($line =~ /\/\*/))
|
||||||
{
|
{
|
||||||
$comment = 1;
|
$comment = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,7 @@ private:
|
||||||
ASSERT_EQUALS(false , MathLib::isFloat("+1E+10000"));
|
ASSERT_EQUALS(false , MathLib::isFloat("+1E+10000"));
|
||||||
ASSERT_EQUALS(false , MathLib::isFloat("-1E+1"));
|
ASSERT_EQUALS(false , MathLib::isFloat("-1E+1"));
|
||||||
ASSERT_EQUALS(false , MathLib::isFloat("-1E+10000"));
|
ASSERT_EQUALS(false , MathLib::isFloat("-1E+10000"));
|
||||||
|
ASSERT_EQUALS(true , MathLib::isFloat(".1250E+04"));
|
||||||
ASSERT_EQUALS(true , MathLib::isFloat("-1E-1"));
|
ASSERT_EQUALS(true , MathLib::isFloat("-1E-1"));
|
||||||
ASSERT_EQUALS(true , MathLib::isFloat("-1E-10000"));
|
ASSERT_EQUALS(true , MathLib::isFloat("-1E-10000"));
|
||||||
|
|
||||||
|
|
|
@ -1625,7 +1625,7 @@ private:
|
||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
|
ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
|
||||||
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str());
|
" bytes of \'p\'\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" memset(p, sizeof(p), 0)\n"
|
" memset(p, sizeof(p), 0)\n"
|
||||||
|
@ -1633,6 +1633,7 @@ private:
|
||||||
);
|
);
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
|
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
|
||||||
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str());
|
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str());
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,7 @@ private:
|
||||||
TEST_CASE(simplifyTypedef72); // ticket #2375
|
TEST_CASE(simplifyTypedef72); // ticket #2375
|
||||||
TEST_CASE(simplifyTypedef73); // ticket #2412
|
TEST_CASE(simplifyTypedef73); // ticket #2412
|
||||||
TEST_CASE(simplifyTypedef74); // ticket #2414
|
TEST_CASE(simplifyTypedef74); // ticket #2414
|
||||||
|
TEST_CASE(simplifyTypedef75); // ticket #2426
|
||||||
|
|
||||||
TEST_CASE(simplifyTypedefFunction1);
|
TEST_CASE(simplifyTypedefFunction1);
|
||||||
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
||||||
|
@ -4786,6 +4787,14 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplifyTypedef75() // ticket #2426
|
||||||
|
{
|
||||||
|
const char code[] = "typedef _Packed struct S { long l; }; \n";
|
||||||
|
const std::string expected = ";";
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void simplifyTypedefFunction1()
|
void simplifyTypedefFunction1()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -3776,19 +3776,19 @@ private:
|
||||||
// ticket #346
|
// ticket #346
|
||||||
|
|
||||||
const char code1[] = "void *p = NULL;";
|
const char code1[] = "void *p = NULL;";
|
||||||
const char res1[] = "void * p ; p = NULL ;";
|
const char res1[] = "void * p ; p = 0 ;";
|
||||||
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
|
||||||
|
|
||||||
const char code2[] = "const void *p = NULL;";
|
const char code2[] = "const void *p = NULL;";
|
||||||
const char res2[] = "const void * p ; p = NULL ;";
|
const char res2[] = "const void * p ; p = 0 ;";
|
||||||
ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
|
ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
|
||||||
|
|
||||||
const char code3[] = "void * const p = NULL;";
|
const char code3[] = "void * const p = NULL;";
|
||||||
const char res3[] = "void * const p ; p = NULL ;";
|
const char res3[] = "void * const p ; p = 0 ;";
|
||||||
ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
|
ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
|
||||||
|
|
||||||
const char code4[] = "const void * const p = NULL;";
|
const char code4[] = "const void * const p = NULL;";
|
||||||
const char res4[] = "const void * const p ; p = NULL ;";
|
const char res4[] = "const void * const p ; p = 0 ;";
|
||||||
ASSERT_EQUALS(res4, tokenizeAndStringify(code4));
|
ASSERT_EQUALS(res4, tokenizeAndStringify(code4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3909,7 +3909,7 @@ private:
|
||||||
{
|
{
|
||||||
// ticket #696
|
// ticket #696
|
||||||
const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};";
|
const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};";
|
||||||
const char res[] = "char a [ 10 ] = { '\\0' } ; char b [ 10 ] = { '\\0' } ;";
|
const char res[] = "char a [ 10 ] = { 0 } ; char b [ 10 ] = { 0 } ;";
|
||||||
|
|
||||||
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
||||||
}
|
}
|
||||||
|
@ -3917,7 +3917,7 @@ private:
|
||||||
void vardecl9()
|
void vardecl9()
|
||||||
{
|
{
|
||||||
const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};";
|
const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};";
|
||||||
const char res[] = "char a [ 2 ] = { 'A' , '\\0' } ; char b [ 2 ] = { 'B' , '\\0' } ;";
|
const char res[] = "char a [ 2 ] = { 'A' , 0 } ; char b [ 2 ] = { 'B' , 0 } ;";
|
||||||
|
|
||||||
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
ASSERT_EQUALS(res, tokenizeAndStringify(code));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue