Merge branch 'master' of github.com:danmar/cppcheck

This commit is contained in:
Zachary Blair 2012-01-19 23:02:33 -08:00
commit 0415444e28
17 changed files with 397 additions and 212 deletions

View File

@ -11,34 +11,73 @@
class SelectFilesModel : public QFileSystemModel {
private:
QStringList selected;
QStringList unselected;
/**
* paths that are user-checked. on the screen all children
* for these paths will appear to be checked too unless
* they are "unchecked".
*/
QStringList checked;
/**
* paths that are user-unchecked.
*/
QStringList unchecked;
/**
* Get index in stringlist where start of string matches. If
* many strings in the stringlist match then return the index
* for the longest string.
* \param s stringlist with filepaths
* \param paths stringlist with filepaths
* \param filepath the filepath that is matched against the stringlist
*/
int getindex(const QStringList &s, const QString &filepath) const {
int getindex(const QStringList &paths, const QString &filepath) const {
int matchlen = 0;
int matchindex = -1;
for (int i = 0; i < s.size(); ++i) {
if (filepath.startsWith(s[i])) {
for (int i = 0; i < paths.size(); ++i) {
if (filepath.startsWith(paths[i])) {
// not a real match of paths..
if (s[i].size() < filepath.size() && filepath[s[i].size()] != '/')
if (paths[i].size() < filepath.size() && filepath[paths[i].size()] != '/')
continue;
// paths match. the return value is the index for the
// longest match
if (s[i].size() > matchlen)
if (paths[i].size() > matchlen)
matchindex = i;
}
}
return matchindex;
}
/**
* Is filepath partially checked?
* \param filepath the filepath to investigate
* \param checkindex result from getindex(checked,filepath). If not given the getindex will be called.
* \return true if filepath is partially checked
*/
bool partiallyChecked(const QString &filepath, int checkindex = -2) const {
const QString filepath2 = filepath.endsWith("/") ? filepath : (filepath + "/");
for (int i = 0; i < unchecked.size(); ++i) {
if (unchecked[i].startsWith(filepath2)) {
return true;
}
}
if (checkindex == -2)
checkindex = getindex(checked, filepath);
if (checkindex == -1) {
for (int i = 0; i < checked.size(); ++i) {
if (checked[i].startsWith(filepath2)) {
return true;
}
}
}
return false;
}
public:
SelectFilesModel() : QFileSystemModel() {
class FileLister : private FileList {
@ -61,14 +100,21 @@ public:
QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const {
if (role == Qt::CheckStateRole) {
const QString filepath = filePath(index);
int selindex = getindex(selected, filepath);
int unselindex = getindex(unselected, filepath);
if (selindex >= 0 && unselindex == -1)
const int checkindex = getindex(checked, filepath);
const int uncheckindex = getindex(unchecked, filepath);
// If some children are not checked then this item should be partially checked..
if (partiallyChecked(filepath, checkindex))
return Qt::PartiallyChecked;
// Is item selected but not unselected?
if (checkindex >= 0 && uncheckindex == -1)
return Qt::Checked;
if (selindex >= 0 && unselindex >= 0 &&
selected[selindex].size() > unselected[unselindex].size())
if (checkindex >= 0 && uncheckindex >= 0 &&
checked[checkindex].size() > unchecked[uncheckindex].size())
return Qt::Checked;
// Item is either not selected at all or else it is unselected
return Qt::Unchecked;
}
return QFileSystemModel::data(index, role);
@ -77,35 +123,49 @@ public:
bool setData(const QModelIndex& index, const QVariant& value, int role) {
if (role == Qt::CheckStateRole) {
const QString filepath = filePath(index);
if (unselected.indexOf(filepath) != -1) {
bool partiallychecked = partiallyChecked(filepath);
if (unchecked.indexOf(filepath) != -1) {
// remove unchecked path
unselected.removeAll(filepath);
} else if (selected.indexOf(filepath) != -1) {
unchecked.removeAll(filepath);
} else if (partiallychecked || checked.indexOf(filepath) != -1) {
// remove child selected paths
for (int i = selected.size() - 1; i >= 0; --i) {
if (selected[i].startsWith(filepath))
selected.removeAt(i);
for (int i = checked.size() - 1; i >= 0; --i) {
if (checked[i].startsWith(filepath))
checked.removeAt(i);
}
// remove child unselected paths
for (int i = unselected.size() - 1; i >= 0; --i) {
if (unselected[i].startsWith(filepath))
unselected.removeAt(i);
for (int i = unchecked.size() - 1; i >= 0; --i) {
if (unchecked[i].startsWith(filepath))
unchecked.removeAt(i);
}
// If partialChecked then select this item
if (partiallychecked)
checked.append(filepath);
} else {
int selindex = getindex(selected, filepath);
int unselindex = getindex(unselected, filepath);
if (selindex == -1)
selected.append(filepath);
else if (unselindex >= 0 && selected[selindex].size() < unselected[unselindex].size())
selected.append(filepath);
const int checkindex = getindex(checked, filepath);
const int uncheckindex = getindex(unchecked, filepath);
if (checkindex == -1)
checked.append(filepath);
else if (uncheckindex >= 0 && checked[checkindex].size() < unchecked[uncheckindex].size())
checked.append(filepath);
else
unselected.append(filepath);
unchecked.append(filepath);
}
if (rowCount(index) > 0)
emit(dataChanged(index, index.child(rowCount(index)-1,0)));
// update parents
QModelIndex parent = index.parent();
while (parent != QModelIndex()) {
emit(dataChanged(parent,parent));
parent = parent.parent();
}
return true;
}
return QFileSystemModel::setData(index, value, role);
@ -114,20 +174,20 @@ public:
QStringList getFiles() const {
QStringList ret;
// List all files in "selected" folders..
// List all files in "checked" folders..
FileList fileLister;
fileLister.AddPathList(selected);
fileLister.AddPathList(checked);
ret = fileLister.GetFileList();
// Remove all items from ret that are unselected but not selected..
// Remove all items from ret that are unchecked but not checked..
for (int i = ret.size() - 1; i >= 0; i--) {
int unselindex = getindex(unselected, ret[i]);
if (unselindex == -1)
int uncheckindex = getindex(unchecked, ret[i]);
if (uncheckindex == -1)
continue;
// both selected and unselected, check which to rely on
int selindex = getindex(selected, ret[i]);
if (selected[selindex].size() < unselected[unselindex].size())
// both checked and unchecked, check which to rely on
int checkindex = getindex(checked, ret[i]);
if (checked[checkindex].size() < unchecked[uncheckindex].size())
ret.removeAt(i);
}

View File

@ -442,15 +442,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
// the function is external and it's neither friend nor inherited virtual function.
// assume all variables that are passed to it are initialized..
else {
unsigned int indentlevel2 = 0;
for (const Token *tok = ftok->tokAt(2); tok; tok = tok->next()) {
if (tok->str() == "(")
++indentlevel2;
else if (tok->str() == ")") {
if (indentlevel2 == 0)
break;
--indentlevel2;
}
for (const Token *tok = ftok->tokAt(2); tok && tok != ftok->next()->link(); tok = tok->next()) {
if (tok->isName()) {
assignVar(tok->str(), scope, usage);
}

View File

@ -434,23 +434,14 @@ void CheckNullPointer::nullPointerLinkedList()
const std::string varname(tok2->str());
// Check usage of dereferenced variable in the loop..
unsigned int indentlevel3 = 0;
for (const Token *tok3 = tok1->next()->link(); tok3; tok3 = tok3->next()) {
if (tok3->str() == "{")
++indentlevel3;
else if (tok3->str() == "}") {
if (indentlevel3 <= 1)
break;
--indentlevel3;
}
for (const Token *tok3 = i->classStart; tok3 && tok3 != i->classEnd; tok3 = tok3->next()) {
// TODO: are there false negatives for "while ( %varid% ||"
else if (Token::Match(tok3, "while ( %varid% &&|)", varid)) {
if (Token::Match(tok3, "while ( %varid% &&|)", varid)) {
// Make sure there is a "break" or "return" inside the loop.
// Without the "break" a null pointer could be dereferenced in the
// for statement.
// indentlevel4 is a counter for { and }. When scanning the code with tok4
unsigned int indentlevel4 = indentlevel3;
unsigned int indentlevel4 = 1;
for (const Token *tok4 = tok3->next()->link(); tok4; tok4 = tok4->next()) {
if (tok4->str() == "{")
++indentlevel4;

View File

@ -1212,7 +1212,8 @@ void CheckOther::invalidScanf()
}
else if (std::isalpha(formatstr[i])) {
invalidScanfError(tok);
if (formatstr[i] != 'c') // #3490 - field width limits are not necessary for %c
invalidScanfError(tok);
format = false;
}
}
@ -1747,8 +1748,7 @@ void CheckOther::checkVariableScope()
continue;
// Walk through all tokens..
unsigned int indentlevel = 0;
for (const Token *tok = scope->classStart; tok; tok = tok->next()) {
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
// Skip function local class and struct declarations..
if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union")) {
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
@ -1764,15 +1764,7 @@ void CheckOther::checkVariableScope()
break;
}
else if (tok->str() == "{") {
++indentlevel;
} else if (tok->str() == "}") {
if (!indentlevel)
break;
--indentlevel;
}
if (indentlevel > 0 && Token::Match(tok, "[{};]")) {
if (Token::Match(tok, "[{};]")) {
// First token of statement..
const Token *tok1 = tok->next();
if (! tok1)
@ -2004,7 +1996,7 @@ void CheckOther::checkCharVariable()
continue;
// This is an error..
charBitOpError(tok);
charBitOpError(tok->tokAt(4));
}
else if (Token::Match(tok, "[;{}] %var% = %any% [&|] ( * %var% ) ;")) {
@ -2021,7 +2013,7 @@ void CheckOther::checkCharVariable()
continue;
// This is an error..
charBitOpError(tok);
charBitOpError(tok->tokAt(4));
}
}
}

View File

@ -67,6 +67,7 @@ public:
checkOther.checkDuplicateExpression();
checkOther.checkUnreachableCode();
checkOther.checkSuspiciousSemicolon();
checkOther.checkWrongPrintfScanfArguments();
// information checks
checkOther.checkVariableScope();
@ -91,7 +92,6 @@ public:
checkOther.checkCCTypeFunctions();
checkOther.checkFflushOnInputStream();
checkOther.invalidScanf();
checkOther.checkWrongPrintfScanfArguments();
checkOther.checkCoutCerrMisusage();
checkOther.checkIncorrectLogicOperator();

View File

@ -265,35 +265,16 @@ void CheckStl::stlOutOfBounds()
continue;
// check if the for loop condition is wrong
unsigned int indent = 0;
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(")
++indent;
else if (tok2->str() == ")") {
if (indent == 0)
break;
--indent;
}
for (const Token *tok2 = tok->tokAt(2); tok2 && tok2 != tok->next()->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, "; %var% <= %var% . size ( ) ;")) {
// Count { and } for tok3
unsigned int indent3 = 0;
// variable id for loop variable.
unsigned int numId = tok2->next()->varId();
// variable id for the container variable
unsigned int varId = tok2->tokAt(3)->varId();
for (const Token *tok3 = tok2->tokAt(8); tok3; tok3 = tok3->next()) {
if (tok3->str() == "{")
++indent3;
else if (tok3->str() == "}") {
if (indent3 <= 1)
break;
--indent3;
} else if (tok3->varId() == varId) {
for (const Token *tok3 = tok2->tokAt(8); tok3 && tok3 != i->classEnd; tok3 = tok3->next()) {
if (tok3->varId() == varId) {
if (Token::simpleMatch(tok3->next(), ". size ( )"))
break;
else if (Token::Match(tok3->next(), "[ %varid% ]", numId))

View File

@ -830,15 +830,7 @@ private:
// Check that the variable hasn't been initialized and
// that it isn't initialized in the body..
if (varid1.find(varid) == varid1.end()) {
unsigned int indentlevel = 0;
for (const Token *tok3 = tok2->tokAt(5); tok3; tok3 = tok3->next()) {
if (tok3->str() == "{")
++indentlevel;
else if (tok3->str() == "}") {
if (indentlevel == 0)
break;
--indentlevel;
}
for (const Token *tok3 = tok2->tokAt(5); tok3 && tok3 != tok2->linkAt(4); tok3 = tok3->next()) {
if (tok3->varId() == varid) {
varid = 0; // variable is used.. maybe it's initialized. clear the variable id.
break;

View File

@ -2546,7 +2546,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
std::map<std::string, PreprocessorMacro *>::iterator it;
for (it = macros.begin(); it != macros.end(); ++it)
delete it->second;
macros.clear();
return "";
}
@ -2628,7 +2628,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
std::map<std::string, PreprocessorMacro *>::iterator iter;
for (iter = macros.begin(); iter != macros.end(); ++iter)
delete iter->second;
macros.clear();
return "";
}
@ -2681,6 +2681,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
for (std::map<std::string, PreprocessorMacro *>::iterator it = macros.begin(); it != macros.end(); ++it)
delete it->second;
macros.clear();
return ostr.str();
}

View File

@ -76,7 +76,7 @@ const Token* TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(Token *to
// check for more complicated syntax errors when using templates..
for (const Token *tok = tokens; tok; tok = tok->next()) {
// skip executing scopes..
if (Token::Match(tok, ") const| {") || Token::Match(tok, "[,=] {")) {
if (Token::simpleMatch(tok, ") {") || Token::Match(tok, ") %var% {") || Token::Match(tok, "[,=] {")) {
while (tok->str() != "{")
tok = tok->next();
tok = tok->link();
@ -243,6 +243,7 @@ void TemplateSimplifier::removeTemplates(Token *tok)
} else if (tok2->str() == ")") { // garbage code! (#3504)
Token::eraseTokens(tok,tok2);
tok->deleteThis();
break;
}
else if (tok2->str() == "{") {
@ -534,8 +535,16 @@ void TemplateSimplifier::simplifyTemplatesUseDefaultArgumentValues(const std::li
}
for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it) {
(*it)->deleteNext();
(*it)->deleteThis();
Token * const eqtok = *it;
const Token *tok2;
for (tok2 = eqtok->next(); tok2; tok2 = tok2->next()) {
if (tok2->str() == "(")
tok2 = tok2->link();
else if (tok2->str() == "," || tok2->str() == ">")
break;
}
Token::eraseTokens(eqtok, tok2);
eqtok->deleteThis();
}
}
}

View File

@ -3892,6 +3892,10 @@ void Tokenizer::simplifyFlowControl()
}
if (tok->str() == "{") {
if (tok->previous() && tok->previous()->str() == "=") {
tok = tok->link();
continue;
}
beginindent = tok;
++indentlevel;
} else if (tok->str() == "}") {
@ -4144,20 +4148,25 @@ bool Tokenizer::simplifyIfAddBraces()
}
if (Token::Match(tok, "if|for|while|BOOST_FOREACH (")) {
if (tok->strAt(2) == ")") {
//no arguments inside round braces, abort
syntaxError(tok);
return false;
}
// don't add "{}" around ";" in "do {} while();" (#609)
const Token *prev = tok->previous();
if (Token::simpleMatch(prev, "} while") &&
prev->link() &&
prev->link()->previous() &&
prev->link()->previous()->str() == "do") {
continue;
if (prev && prev->str() == "}" && tok->str() == "while") {
prev = prev->link()->previous();
if (prev && prev->str() == "do")
continue;
}
// Goto the ending ')'
tok = tok->next()->link();
// ')' should be followed by '{'
if (Token::simpleMatch(tok, ") {"))
// there's already '{' after ')', don't bother
if (tok->next() && tok->next()->str() == "{")
continue;
}
@ -4171,11 +4180,10 @@ bool Tokenizer::simplifyIfAddBraces()
continue;
}
// If there is no code after the if(), abort
// If there is no code after the 'if()' or 'else', abort
if (!tok->next()) {
// This is a syntax error and we should call syntaxError() and return false but
// many tokenizer tests are written with this syntax error so just ignore it.
return true;
syntaxError(tok);
return false;
}
// insert open brace..
@ -4183,7 +4191,7 @@ bool Tokenizer::simplifyIfAddBraces()
tok = tok->next();
Token *tempToken = tok;
bool innerIf = Token::simpleMatch(tempToken->next(), "if");
bool innerIf = (tempToken->next() && tempToken->next()->str() == "if");
if (Token::simpleMatch(tempToken->next(), "do {"))
tempToken = tempToken->linkAt(2);
@ -4196,7 +4204,12 @@ bool Tokenizer::simplifyIfAddBraces()
// * if (cond1) if (cond2) ; else ;
while (NULL != (tempToken = tempToken->next())) {
if (tempToken->str() == "{") {
if (Token::simpleMatch(tempToken->previous(),"else {")) {
if (tempToken->previous()->str() == "=") {
tempToken = tempToken->link();
continue;
}
if (tempToken->previous()->str() == "else") {
if (innerIf)
tempToken = tempToken->link();
else
@ -4204,7 +4217,7 @@ bool Tokenizer::simplifyIfAddBraces()
break;
}
tempToken = tempToken->link();
if (!tempToken || !tempToken->next())
if (!tempToken->next())
break;
if (Token::simpleMatch(tempToken, "} else") && !Token::Match(tempToken->tokAt(2), "if|{"))
innerIf = false;
@ -4228,11 +4241,10 @@ bool Tokenizer::simplifyIfAddBraces()
if (!innerIf)
break;
if (Token::simpleMatch(tempToken, "; else if"))
;
else if (Token::simpleMatch(tempToken, "; else"))
innerIf = false;
else
if (Token::simpleMatch(tempToken, "; else")) {
if (tempToken->strAt(2) != "if")
innerIf = false;
} else
break;
}
}
@ -5294,14 +5306,14 @@ void Tokenizer::simplifyPlatformTypes()
_settings->platformType == Settings::Win32W ||
_settings->platformType == Settings::Win64) {
for (Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "BOOL|INT|INT32"))
if (Token::Match(tok, "BOOL|INT|INT32|HFILE|LONG32"))
tok->str("int");
else if (Token::Match(tok, "BOOLEAN|BYTE|UCHAR")) {
tok->str("unsigned");
tok->insertToken("char");
} else if (tok->str() == "CHAR")
tok->str("char");
else if (Token::Match(tok, "DWORD|ULONG|COLORREF")) {
else if (Token::Match(tok, "DWORD|ULONG|COLORREF|LCID|LCTYPE|LGRPID")) {
tok->str("unsigned");
tok->insertToken("long");
} else if (Token::Match(tok, "DWORD_PTR|ULONG_PTR|SIZE_T")) {
@ -5311,21 +5323,19 @@ void Tokenizer::simplifyPlatformTypes()
tok->insertToken("long");
} else if (tok->str() == "FLOAT")
tok->str("float");
else if (tok->str() == "HRESULT")
else if (Token::Match(tok, "HRESULT|LONG"))
tok->str("long");
else if (tok->str() == "INT64") {
else if (Token::Match(tok, "INT64|LONG64")) {
tok->str("long");
tok->insertToken("long");
} else if (tok->str() == "LONG")
tok->str("long");
else if (Token::Match(tok, "LONG_PTR|LPARAM|LRESULT")) {
} else if (Token::Match(tok, "LONG_PTR|LPARAM|LRESULT|SSIZE_T")) {
tok->str("long");
if (_settings->platformType == Settings::Win64)
tok->insertToken("long");
} else if (Token::Match(tok, "LPBOOL|PBOOL")) {
tok->str("int");
tok->insertToken("*");
} else if (Token::Match(tok, "LPBYTE|PBOOLEAN|PBYTE")) {
} else if (Token::Match(tok, "LPBYTE|PBOOLEAN|PBYTE|PUCHAR")) {
tok->str("unsigned");
tok->insertToken("*");
tok->insertToken("char");
@ -5337,7 +5347,7 @@ void Tokenizer::simplifyPlatformTypes()
tok->str("const");
tok->insertToken("*");
tok->insertToken("void");
} else if (tok->str() == "LPDWORD") {
} else if (Token::Match(tok, "LPDWORD|LPCOLORREF|PDWORD|PULONG")) {
tok->str("unsigned");
tok->insertToken("*");
tok->insertToken("long");
@ -5350,28 +5360,31 @@ void Tokenizer::simplifyPlatformTypes()
} else if (Token::Match(tok, "LPSTR|PSTR|PCHAR")) {
tok->str("char");
tok->insertToken("*");
} else if (Token::Match(tok, "LPVOID|PVOID|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCURSOR|HDC|HFONT|HGDIOBJ|HGLOBAL|HICON|HINSTANCE|HKEY|HLOCAL|HMENU|HMETAFILE|HMODULE|HPALETTE|HPEN|HRGN|HRSRC|HWND")) {
} else if (Token::Match(tok, "LPVOID|PVOID|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCURSOR|HDC|HFONT|HGDIOBJ|HGLOBAL|HICON|HINSTANCE|HKEY|HLOCAL|HMENU|HMETAFILE|HMODULE|HPALETTE|HPEN|HRGN|HRSRC|HWND|SERVICE_STATUS_HANDLE|SC_LOCK|SC_HANDLE|HACCEL|HCONV|HCONVLIST|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HHOOK|HKL|HMONITOR|HSZ|HWINSTA")) {
tok->str("void");
tok->insertToken("*");
} else if ((tok->str() == "PHANDLE")) {
tok->str("void");
tok->insertToken("*");
tok->insertToken("*");
} else if (Token::Match(tok, "LPWORD|PWORD")) {
} else if (Token::Match(tok, "LPWORD|PWORD|PWSTR|PWCHAR|PUSHORT")) {
tok->str("unsigned");
tok->insertToken("*");
tok->insertToken("short");
} else if (tok->str() == "SHORT")
tok->str("short");
else if (Token::Match(tok, "UINT|MMRESULT|SOCKET")) {
else if (Token::Match(tok, "UINT|MMRESULT|SOCKET|ULONG32|UINT32|DWORD32")) {
tok->str("unsigned");
tok->insertToken("int");
} else if (Token::Match(tok, "UINT_PTR|WPARAM")) {
tok->str("unsigned");
tok->insertToken("long");
if (_settings->platformType == Settings::Win64)
if (_settings->platformType == Settings::Win64) {
tok->insertToken("long");
} else if (Token::Match(tok, "USHORT|WORD|WCHAR|ATOM|wchar_t")) {
tok->insertToken("long");
} else {
tok->insertToken("int");
}
} else if (Token::Match(tok, "USHORT|WORD|WCHAR|ATOM|wchar_t|LANGID")) {
tok->str("unsigned");
tok->insertToken("short");
} else if (tok->str() == "VOID")
@ -5383,6 +5396,12 @@ void Tokenizer::simplifyPlatformTypes()
tok->str("unsigned");
tok->insertToken("short");
}
} else if (tok->str() == "TBYTE") {
tok->str("unsigned");
if (_settings->platformType == Settings::Win32A)
tok->insertToken("short");
else
tok->insertToken("char");
} else if (Token::Match(tok, "PTSTR|LPTSTR")) {
if (_settings->platformType == Settings::Win32A) {
tok->str("char");
@ -5393,16 +5412,35 @@ void Tokenizer::simplifyPlatformTypes()
tok->insertToken("short");
}
} else if (Token::Match(tok, "PCTSTR|LPCTSTR")) {
tok->str("const");
if (_settings->platformType == Settings::Win32A) {
tok->str("const");
tok->insertToken("*");
tok->insertToken("char");
} else {
tok->str("const");
tok->insertToken("*");
tok->insertToken("short");
tok->insertToken("unsigned");
}
} else if (Token::Match(tok, "ULONG64|DWORD64")) {
tok->str("unsigned");
tok->insertToken("long");
} else if (tok->str() == "HALF_PTR") {
if (_settings->platformType == Settings::Win64)
tok->str("int");
else
tok->str("short");
} else if (tok->str() == "INT_PTR") {
if (_settings->platformType == Settings::Win64) {
tok->str("long");
tok->insertToken("long");
} else {
tok->str("int");
}
} else if (tok->str() == "LPCWSTR") {
tok->str("const");
tok->insertToken("*");
tok->insertToken("short");
tok->insertToken("unsigned");
}
}
}
@ -6707,10 +6745,8 @@ void Tokenizer::simplifyGoto()
}
}
if (!indentlevel && Token::Match(tok, ") const| {")) {
gotos.clear();
if (!indentlevel && Token::Match(tok, ") const| {"))
beginfunction = tok;
}
else if (indentlevel && Token::Match(tok, "[{};] goto %var% ;"))
gotos.push_back(tok->next());
@ -7014,22 +7050,25 @@ void Tokenizer::simplifyEnum()
tok = tok->previous();
}
if (Token::Match(tok, "class|struct|namespace %any%") &&
if (Token::Match(tok, "class|struct|namespace") && tok->next() &&
(!tok->previous() || (tok->previous() && tok->previous()->str() != "enum"))) {
className = tok->next()->str();
classLevel = 0;
continue;
} else if (tok->str() == "}") {
--classLevel;
if (classLevel < 0)
className = "";
continue;
} else if (tok->str() == "{") {
++classLevel;
continue;
} else if (Token::Match(tok, "enum class|struct| {|:") ||
Token::Match(tok, "enum class|struct| %type% {|:|;")) {
} else if (tok->str() == "enum") {
Token *temp = tok->next();
if (!temp)
break;
if (Token::Match(temp, "class|struct"))
temp = temp->next();
if (!Token::Match(temp, "[{:]") &&
(!temp->isName() || !Token::Match(temp->next(), "[{:;]")))
continue;
Token *start = tok;
Token *enumType = 0;
Token *typeTokenStart = 0;
@ -7040,7 +7079,7 @@ void Tokenizer::simplifyEnum()
tok->deleteNext();
// check for name
if (Token::Match(tok->next(), "%type%")) {
if (tok->next()->isName()) {
enumType = tok->next();
tok = tok->next();
}

View File

@ -28,4 +28,5 @@ astyle $style $options test/*.cpp
astyle $style $options test/*.h
astyle $style $options tools/*.cpp
astyle $style $options --recursive "samples/*.c"

View File

@ -0,0 +1,11 @@
int foo(int *p)
{
int a = p;
return a + 4;
}
int main()
{
int i[10];
foo(i);
}

View File

@ -0,0 +1,11 @@
int* foo(int *p)
{
return p + 4;
}
int main()
{
int i[10];
foo(i);
}

View File

@ -112,7 +112,7 @@ private:
" char ch;\n"
" result = a | ch;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
ASSERT_EQUALS("[test.cpp:5]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
}
void bitop2() {
@ -159,7 +159,7 @@ private:
" ret |= *p;\n"
" return ret;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (warning) When using char variables in bit operations, sign extension can generate unexpected results.\n", errout.str());
// fixed code
check("void f(char *p) {\n"

View File

@ -88,6 +88,7 @@ private:
TEST_CASE(testScanf1);
TEST_CASE(testScanf2);
TEST_CASE(testScanf3);
TEST_CASE(testScanf4);
TEST_CASE(testScanfArgument);
TEST_CASE(testPrintfArgument);
@ -2028,9 +2029,9 @@ private:
" fclose(file);\n"
" return b;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str());
ASSERT_EQUALS("[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n"
"[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n", errout.str());
}
void testScanf2() {
@ -2045,9 +2046,9 @@ private:
" fclose(file);\n"
" return b;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str());
ASSERT_EQUALS("[test.cpp:8]: (warning) fscanf format string has 0 parameters but 1 are given\n"
"[test.cpp:6]: (warning) scanf without field width limits can crash with huge input data\n"
"[test.cpp:7]: (warning) scanf without field width limits can crash with huge input data\n", errout.str());
}
void testScanf3() {
@ -2076,6 +2077,14 @@ private:
ASSERT_EQUALS("[test.cpp:7]: (warning) fscanf format string has 0 parameters but 1 are given\n", errout.str());
}
void testScanf4() {
check("void f() {\n"
" char c;\n"
" scanf(\"%c\", &c);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void testScanfArgument() {
check("void foo() {\n"
" scanf(\"%1d\", &foo);\n"
@ -2213,6 +2222,7 @@ private:
" printf(\"%G\", bp);\n"
" printf(\"%f\", d);\n"
" printf(\"%f\", b);\n"
" printf(\"%f\", (float)cpi);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning) %e in format string (no. 1) requires a floating point number given in the argument list\n"
"[test.cpp:4]: (warning) %E in format string (no. 1) requires a floating point number given in the argument list\n"

View File

@ -447,7 +447,7 @@ private:
void cast() {
ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)0)"));
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)0);"));
ASSERT_EQUALS("return str ;", tok("return (char *)str;"));
{
@ -469,7 +469,7 @@ private:
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)"));
ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };"));
ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };"));
ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)(char *)0)"));
ASSERT_EQUALS("if ( ! p ) { ; }", tok("if (p == (char *)(char *)0);"));
// no simplification as the cast may be important here. see #2897 for example
ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;"));
@ -2439,17 +2439,17 @@ private:
}
void ifnot() {
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(0==x)"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(x==0)"));
ASSERT_EQUALS("if ( ! ( a = b ) )", simplifyIfNot("if(0==(a=b))"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if(x==0)"));
ASSERT_EQUALS("if ( ! a && b ( ) )", simplifyIfNot("if( 0 == a && b() )"));
ASSERT_EQUALS("if ( b ( ) && ! a )", simplifyIfNot("if( b() && 0 == a )"));
ASSERT_EQUALS("if ( ! ( a = b ) )", simplifyIfNot("if((a=b)==0)"));
ASSERT_EQUALS("if ( ! x . y )", simplifyIfNot("if(x.y==0)"));
ASSERT_EQUALS("if ( ! x )", simplifyIfNot("if((x==0))"));
ASSERT_EQUALS("if ( ( ! x ) && ! y )", simplifyIfNot("if((x==0) && y==0)"));
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) )", simplifyIfNot("if(!(fclose(fd) == 0))"));
ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(0==x);"));
ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(x==0);"));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", simplifyIfNot("if(0==(a=b));"));
ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if(x==0);"));
ASSERT_EQUALS("if ( ! a && b ( ) ) { ; }", simplifyIfNot("if( 0 == a && b() );"));
ASSERT_EQUALS("if ( b ( ) && ! a ) { ; }", simplifyIfNot("if( b() && 0 == a );"));
ASSERT_EQUALS("if ( ! ( a = b ) ) { ; }", simplifyIfNot("if((a=b)==0);"));
ASSERT_EQUALS("if ( ! x . y ) { ; }", simplifyIfNot("if(x.y==0);"));
ASSERT_EQUALS("if ( ! x ) { ; }", simplifyIfNot("if((x==0));"));
ASSERT_EQUALS("if ( ( ! x ) && ! y ) { ; }", simplifyIfNot("if((x==0) && y==0);"));
ASSERT_EQUALS("if ( ! ( ! fclose ( fd ) ) ) { ; }", simplifyIfNot("if(!(fclose(fd) == 0));"));
}
@ -2470,8 +2470,8 @@ private:
}
void not1() {
ASSERT_EQUALS("if ( ! p )", simplifyLogicalOperators("if (not p)"));
ASSERT_EQUALS("if ( p && ! q )", simplifyLogicalOperators("if (p && not q)"));
ASSERT_EQUALS("if ( ! p ) { ; }", simplifyLogicalOperators("if (not p);"));
ASSERT_EQUALS("if ( p && ! q ) { ; }", simplifyLogicalOperators("if (p && not q);"));
ASSERT_EQUALS("void foo ( not i )", simplifyLogicalOperators("void foo ( not i )"));
}
@ -2488,8 +2488,8 @@ private:
ASSERT_EQUALS("if ( p && bar ( ) ) { ; }",
simplifyLogicalOperators("if (p and bar()) ;"));
ASSERT_EQUALS("if ( p && ! q )",
simplifyLogicalOperators("if (p and not q)"));
ASSERT_EQUALS("if ( p && ! q ) { ; }",
simplifyLogicalOperators("if (p and not q) ;"));
}
void or1() {
@ -2505,8 +2505,8 @@ private:
ASSERT_EQUALS("if ( p || bar ( ) ) { ; }",
simplifyLogicalOperators("if (p or bar()) ;"));
ASSERT_EQUALS("if ( p || ! q )",
simplifyLogicalOperators("if (p or not q)"));
ASSERT_EQUALS("if ( p || ! q ) { ; }",
simplifyLogicalOperators("if (p or not q) ;"));
}
void comma_keyword() {
@ -2800,9 +2800,9 @@ private:
ASSERT_EQUALS(";", tok("; x = x + 0;"));
ASSERT_EQUALS("if ( a == 2 )", tok("if (a==1+1)"));
ASSERT_EQUALS("if ( a + 2 != 6 )", tok("if (a+1+1!=1+2+3)"));
ASSERT_EQUALS("if ( 4 < a )", tok("if (14-2*5<a*4/(2*2))"));
ASSERT_EQUALS("if ( a == 2 ) { ; }", tok("if (a==1+1);"));
ASSERT_EQUALS("if ( a + 2 != 6 ) { ; }", tok("if (a+1+1!=1+2+3);"));
ASSERT_EQUALS("if ( 4 < a ) { ; }", tok("if (14-2*5<a*4/(2*2));"));
ASSERT_EQUALS("( y / 2 - 2 )", tok("(y / 2 - 2)"));
ASSERT_EQUALS("( y % 2 - 2 )", tok("(y % 2 - 2)"));

View File

@ -598,8 +598,13 @@ private:
ASSERT_EQUALS("( X && Y )", tokenizeAndStringify("(X&&Y)"));
}
void tokenize19() { // #3006 (segmentation fault)
void tokenize19() {
// #3006 - added hasComplicatedSyntaxErrorsInTemplates to avoid segmentation fault
tokenizeAndStringify("x < () <");
// #3496 - make sure hasComplicatedSyntaxErrorsInTemplates works
ASSERT_EQUALS("void a ( Fred * f ) { for ( ; n < f . x ( ) ; ) { } }",
tokenizeAndStringify("void a(Fred* f) MACRO { for (;n < f->x();) {} }"));
}
void tokenize20() { // replace C99 _Bool => bool
@ -759,7 +764,7 @@ private:
void removeCast6() {
// ticket #2103
ASSERT_EQUALS("if ( ! x )", tokenizeAndStringify("if (x == (char *) ((void *)0))", true));
ASSERT_EQUALS("if ( ! x ) { ; }", tokenizeAndStringify("if (x == (char *) ((void *)0)) ;", true));
}
void removeCast7() {
@ -771,16 +776,16 @@ private:
}
void inlineasm() {
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";_asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify(";__asm { mov ax,bx };"));
ASSERT_EQUALS("; asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";__asm__ __volatile__ ( \"mov ax,bx\" );"));
ASSERT_EQUALS("; asm ( \"_emit 12h\" ) ;", tokenizeAndStringify(";__asm _emit 12h ;"));
ASSERT_EQUALS("; asm ( \"mov a , b\" ) ;", tokenizeAndStringify(";__asm mov a, b ;"));
ASSERT_EQUALS("; asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(";asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("; asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("; __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("; asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify("; __asm __volatile__ (\"ddd\") ;"));
ASSERT_EQUALS("; asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";__asm__ volatile ( \"mov ax,bx\" );"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("_asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"mov ax , bx\" ) ;", tokenizeAndStringify("__asm { mov ax,bx };"));
ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ __volatile__ ( \"mov ax,bx\" );"));
ASSERT_EQUALS("asm ( \"_emit 12h\" ) ;", tokenizeAndStringify("__asm _emit 12h ;"));
ASSERT_EQUALS("asm ( \"mov a , b\" ) ;", tokenizeAndStringify("__asm mov a, b ;"));
ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify("asm volatile (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("asm ( \"\"fnstcw %0\" : \"= m\" ( old_cw )\" ) ;", tokenizeAndStringify(" __asm__ (\"fnstcw %0\" : \"= m\" (old_cw));"));
ASSERT_EQUALS("asm ( \"\"ddd\"\" ) ;", tokenizeAndStringify(" __asm __volatile__ (\"ddd\") ;"));
ASSERT_EQUALS("asm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify("__asm__ volatile ( \"mov ax,bx\" );"));
// 'asm ( ) ;' should be in the same line
ASSERT_EQUALS(";\n\nasm ( \"\"mov ax,bx\"\" ) ;", tokenizeAndStringify(";\n\n__asm__ volatile ( \"mov ax,bx\" );", true));
@ -5869,14 +5874,14 @@ private:
}
void simplifyLogicalOperators() {
ASSERT_EQUALS("if ( a && b )", tokenizeAndStringify("if (a and b)"));
ASSERT_EQUALS("if ( a || b )", tokenizeAndStringify("if (a or b)"));
ASSERT_EQUALS("if ( a & b )", tokenizeAndStringify("if (a bitand b)"));
ASSERT_EQUALS("if ( a | b )", tokenizeAndStringify("if (a bitor b)"));
ASSERT_EQUALS("if ( a ^ b )", tokenizeAndStringify("if (a xor b)"));
ASSERT_EQUALS("if ( ~ b )", tokenizeAndStringify("if (compl b)"));
ASSERT_EQUALS("if ( ! b )", tokenizeAndStringify("if (not b)"));
ASSERT_EQUALS("if ( a != b )", tokenizeAndStringify("if (a not_eq b)"));
ASSERT_EQUALS("if ( a && b ) { ; }", tokenizeAndStringify("if (a and b);"));
ASSERT_EQUALS("if ( a || b ) { ; }", tokenizeAndStringify("if (a or b);"));
ASSERT_EQUALS("if ( a & b ) { ; }", tokenizeAndStringify("if (a bitand b);"));
ASSERT_EQUALS("if ( a | b ) { ; }", tokenizeAndStringify("if (a bitor b);"));
ASSERT_EQUALS("if ( a ^ b ) { ; }", tokenizeAndStringify("if (a xor b);"));
ASSERT_EQUALS("if ( ~ b ) { ; }", tokenizeAndStringify("if (compl b);"));
ASSERT_EQUALS("if ( ! b ) { ; }", tokenizeAndStringify("if (not b);"));
ASSERT_EQUALS("if ( a != b ) { ; }", tokenizeAndStringify("if (a not_eq b);"));
}
void simplifyCalculations() {
@ -6099,6 +6104,7 @@ private:
}
void platformWin32() {
// WIN32A
const char code[] = "unsigned int sizeof_short = sizeof(short);"
"unsigned int sizeof_unsigned_short = sizeof(unsigned short);"
"unsigned int sizeof_int = sizeof(int);"
@ -6158,7 +6164,45 @@ private:
"SIZE_T Q;"
"HRESULT R;"
"LONG_PTR S;"
"HANDLE T;";
"HANDLE T;"
"BOOL _bool;"
"HFILE hfile;"
"LONG32 long32;"
"LCID lcid;"
"LCTYPE lctype;"
"LGRPID lgrpid;"
"LONG64 long64;"
"SSIZE_T _ssize_t;"
"PUCHAR puchar;"
"LPCOLORREF lpcolorref;"
"PDWORD pdword;"
"PULONG pulong;"
"SERVICE_STATUS_HANDLE service_status_hanlde;"
"SC_LOCK sc_lock;"
"SC_HANDLE sc_handle;"
"HACCEL haccel;"
"HCONV hconv;"
"HCONVLIST hconvlist;"
"HDDEDATA hddedata;"
"HDESK hdesk;"
"HDROP hdrop;"
"HDWP hdwp;"
"HENHMETAFILE henhmetafile;"
"HHOOK hhook;"
"HKL hkl;"
"HMONITOR hmonitor;"
"HSZ hsz;"
"HWINSTA hwinsta;"
"PWCHAR pwchar;"
"PUSHORT pushort;"
"UINT_PTR uint_ptr;"
"WPARAM wparam;"
"LANGID langid;"
"DWORD64 dword64;"
"ULONG64 ulong64;"
"HALF_PTR half_ptr;"
"INT_PTR int_ptr;"
"LPCWSTR lpcwstr;";
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
@ -6219,7 +6263,45 @@ private:
"unsigned long Q ; "
"long R ; "
"long S ; "
"void * T ;";
"void * T ; "
"int _bool ; "
"int hfile ; "
"int long32 ; "
"unsigned long lcid ; "
"unsigned long lctype ; "
"unsigned long lgrpid ; "
"long long long64 ; "
"long _ssize_t ; "
"unsigned char * puchar ; "
"unsigned long * lpcolorref ; "
"unsigned long * pdword ; "
"unsigned long * pulong ; "
"void * service_status_hanlde ; "
"void * sc_lock ; "
"void * sc_handle ; "
"void * haccel ; "
"void * hconv ; "
"void * hconvlist ; "
"void * hddedata ; "
"void * hdesk ; "
"void * hdrop ; "
"void * hdwp ; "
"void * henhmetafile ; "
"void * hhook ; "
"void * hkl ; "
"void * hmonitor ; "
"void * hsz ; "
"void * hwinsta ; "
"unsigned short * pwchar ; "
"unsigned short * pushort ; "
"unsigned int uint_ptr ; "
"unsigned int wparam ; "
"unsigned short langid ; "
"unsigned long dword64 ; "
"unsigned long ulong64 ; "
"short half_ptr ; "
"int int_ptr ; "
"const unsigned short * lpcwstr ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win32A));
}
@ -6244,7 +6326,8 @@ private:
" _sntprintf(dst, sizeof(dst) / sizeof(TCHAR), _T(\"Hello world!\n\"));"
" _tscanf(_T(\"%s\"), dst);"
" _stscanf(dst, _T(\"%s\"), dst);"
"}";
"}"
"TBYTE tbyte;";
const char expected[] = "unsigned short wc ; "
"char c ; "
"char * ptstr ; "
@ -6264,7 +6347,8 @@ private:
"snprintf ( dst , sizeof ( dst ) / sizeof ( char ) , \"Hello world!\n\" ) ; "
"scanf ( \"%s\" , dst ) ; "
"sscanf ( dst , \"%s\" , dst ) ; "
"}";
"} "
"unsigned short tbyte ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false, true, Settings::Win32A));
}
@ -6275,6 +6359,7 @@ private:
"LPTSTR lptstr;"
"PCTSTR pctstr;"
"LPCTSTR lpctstr;"
"TBYTE tbyte;"
"void foo() {"
" TCHAR tc = _T(\'c\');"
" TCHAR src[10] = _T(\"123456789\");"
@ -6295,6 +6380,7 @@ private:
"unsigned short * lptstr ; "
"const unsigned short * pctstr ; "
"const unsigned short * lpctstr ; "
"unsigned char tbyte ; "
"void foo ( ) { "
"unsigned short tc ; tc = \'c\' ; "
"unsigned short src [ 10 ] = \"123456789\" ; "
@ -6337,7 +6423,11 @@ private:
"SIZE_T Q;"
"HRESULT R;"
"LONG_PTR S;"
"HANDLE T;";
"HANDLE T;"
"SSIZE_T _ssize_t;"
"UINT_PTR uint_ptr;"
"WPARAM wparam;"
"INT_PTR int_ptr;";
const char expected[] = "unsigned int sizeof_short ; sizeof_short = 2 ; "
"unsigned int sizeof_unsigned_short ; sizeof_unsigned_short = 2 ; "
@ -6363,7 +6453,12 @@ private:
"unsigned long long Q ; "
"long R ; "
"long long S ; "
"void * T ;";
"void * T ; "
"long long _ssize_t ; "
"unsigned long long uint_ptr ; "
"unsigned long long wparam ; "
"long long int_ptr ;"
;
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, true, Settings::Win64));
}