Fixed #5079 (CheckIO::checkFileUsage doesn't support wide char and microsoft functions)
This commit is contained in:
parent
b1dc51ba9c
commit
cb1fc06a80
|
@ -97,9 +97,10 @@ struct Filepointer {
|
|||
void CheckIO::checkFileUsage()
|
||||
{
|
||||
static const char* _whitelist[] = {
|
||||
"clearerr", "feof", "ferror", "fgetpos", "ftell", "setbuf", "setvbuf", "ungetc"
|
||||
"clearerr", "feof", "ferror", "fgetpos", "ftell", "setbuf", "setvbuf", "ungetc", "ungetwc"
|
||||
};
|
||||
static const std::set<std::string> whitelist(_whitelist, _whitelist + sizeof(_whitelist)/sizeof(*_whitelist));
|
||||
const bool windows = _settings->isWindowsPlatform();
|
||||
|
||||
std::map<unsigned int, Filepointer> filepointers;
|
||||
|
||||
|
@ -147,7 +148,9 @@ void CheckIO::checkFileUsage()
|
|||
i->second.op_indent = 0;
|
||||
i->second.lastOperation = Filepointer::UNKNOWN_OP;
|
||||
}
|
||||
} else if (tok->varId() && Token::Match(tok, "%var% =") && (tok->strAt(2) != "fopen" && tok->strAt(2) != "freopen" && tok->strAt(2) != "tmpfile")) {
|
||||
} else if (tok->varId() && Token::Match(tok, "%var% =") &&
|
||||
(tok->strAt(2) != "fopen" && tok->strAt(2) != "freopen" && tok->strAt(2) != "tmpfile" &&
|
||||
(windows ? (tok->str() != "_wfopen" && tok->str() != "_wfreopen") : true))) {
|
||||
std::map<unsigned int, Filepointer>::iterator i = filepointers.find(tok->varId());
|
||||
if (i != filepointers.end()) {
|
||||
i->second.mode = UNKNOWN;
|
||||
|
@ -158,7 +161,9 @@ void CheckIO::checkFileUsage()
|
|||
const Token* fileTok = 0;
|
||||
Filepointer::Operation operation = Filepointer::NONE;
|
||||
|
||||
if ((tok->str() == "fopen" || tok->str() == "freopen" || tok->str() == "tmpfile") && tok->strAt(-1) == "=") {
|
||||
if ((tok->str() == "fopen" || tok->str() == "freopen" || tok->str() == "tmpfile" ||
|
||||
(windows && (tok->str() == "_wfopen" || tok->str() == "_wfreopen"))) &&
|
||||
tok->strAt(-1) == "=") {
|
||||
if (tok->str() != "tmpfile") {
|
||||
const Token* modeTok = tok->tokAt(2)->nextArgument();
|
||||
if (modeTok && modeTok->type() == Token::eString)
|
||||
|
@ -167,21 +172,34 @@ void CheckIO::checkFileUsage()
|
|||
mode = "wb+";
|
||||
fileTok = tok->tokAt(-2);
|
||||
operation = Filepointer::OPEN;
|
||||
} else if (tok->str() == "rewind" || tok->str() == "fseek" || tok->str() == "fsetpos" || tok->str() == "fflush") {
|
||||
} else if (windows && Token::Match(tok, "fopen_s|freopen_s|_wfopen_s|_wfreopen_s ( & %var%")) {
|
||||
const Token* modeTok = tok->tokAt(2)->nextArgument()->nextArgument();
|
||||
if (modeTok && modeTok->type() == Token::eString)
|
||||
mode = modeTok->strValue();
|
||||
fileTok = tok->tokAt(3);
|
||||
operation = Filepointer::OPEN;
|
||||
} else if ((tok->str() == "rewind" || tok->str() == "fseek" || tok->str() == "fsetpos" || tok->str() == "fflush") ||
|
||||
(windows && tok->str() == "_fseeki64")) {
|
||||
if (Token::simpleMatch(tok, "fflush ( stdin )"))
|
||||
fflushOnInputStreamError(tok, tok->strAt(2));
|
||||
else {
|
||||
fileTok = tok->tokAt(2);
|
||||
operation = Filepointer::POSITIONING;
|
||||
}
|
||||
} else if (tok->str() == "fgetc" || tok->str() == "fgets" || tok->str() == "fread" || tok->str() == "fscanf" || tok->str() == "getc") {
|
||||
if (tok->str() == "fscanf")
|
||||
} else if (tok->str() == "fgetc" || tok->str() == "fgetwc" ||
|
||||
tok->str() == "fgets" || tok->str() == "fgetws" || tok->str() == "fread" ||
|
||||
tok->str() == "fscanf" || tok->str() == "fwscanf" || tok->str() == "getc" ||
|
||||
(windows && (tok->str() == "fscanf_s" || tok->str() == "fwscanf_s"))) {
|
||||
if (tok->str().find("scanf") != std::string::npos)
|
||||
fileTok = tok->tokAt(2);
|
||||
else
|
||||
fileTok = tok->linkAt(1)->previous();
|
||||
operation = Filepointer::READ;
|
||||
} else if (tok->str() == "fputc" || tok->str() == "fputs" || tok->str() == "fwrite" || tok->str() == "fprintf" || tok->str() == "putcc") {
|
||||
if (tok->str() == "fprintf")
|
||||
} else if (tok->str() == "fputc" || tok->str() == "fputwc" ||
|
||||
tok->str() == "fputs" || tok->str() == "fputws" || tok->str() == "fwrite" ||
|
||||
tok->str() == "fprintf" || tok->str() == "fwprintf" || tok->str() == "putcc" ||
|
||||
(windows && (tok->str() == "fprintf_s" || tok->str() == "fwprintf_s"))) {
|
||||
if (tok->str().find("printf") != std::string::npos)
|
||||
fileTok = tok->tokAt(2);
|
||||
else
|
||||
fileTok = tok->linkAt(1)->previous();
|
||||
|
@ -191,7 +209,7 @@ void CheckIO::checkFileUsage()
|
|||
operation = Filepointer::CLOSE;
|
||||
} else if (whitelist.find(tok->str()) != whitelist.end()) {
|
||||
fileTok = tok->tokAt(2);
|
||||
if (tok->str() == "ungetc" && fileTok)
|
||||
if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok)
|
||||
fileTok = fileTok->nextArgument();
|
||||
operation = Filepointer::UNIMPORTANT;
|
||||
} else if (!Token::Match(tok, "if|for|while|catch|switch")) {
|
||||
|
@ -313,6 +331,7 @@ void CheckIO::invalidScanf()
|
|||
if (!_settings->isEnabled("warning") && !_settings->isEnabled("portability"))
|
||||
return;
|
||||
|
||||
const bool windows = _settings->isWindowsPlatform();
|
||||
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t j = 0; j < functions; ++j) {
|
||||
|
@ -348,7 +367,7 @@ void CheckIO::invalidScanf()
|
|||
else if (std::isalpha(formatstr[i]) || formatstr[i] == '[') {
|
||||
if ((formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's')) && _settings->isEnabled("warning")) // #3490 - field width limits are only necessary for string input
|
||||
invalidScanfError(tok, false);
|
||||
else if (formatstr[i] != 'n' && formatstr[i] != 'c' && _settings->platformType != Settings::Win32A && _settings->platformType != Settings::Win32W && _settings->platformType != Settings::Win64 && _settings->isEnabled("portability"))
|
||||
else if (formatstr[i] != 'n' && formatstr[i] != 'c' && !windows && _settings->isEnabled("portability"))
|
||||
invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25
|
||||
format = false;
|
||||
}
|
||||
|
@ -444,8 +463,8 @@ static bool findFormat(unsigned int arg, const Token *firstArg,
|
|||
void CheckIO::checkWrongPrintfScanfArguments()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
bool warning = _settings->isEnabled("warning");
|
||||
bool windows = _settings->isWindowsPlatform();
|
||||
const bool warning = _settings->isEnabled("warning");
|
||||
const bool windows = _settings->isWindowsPlatform();
|
||||
|
||||
std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t j = 0; j < functions; ++j) {
|
||||
|
|
|
@ -9535,32 +9535,58 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
|
|||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "_topen (")) {
|
||||
tok->str("open");
|
||||
tok->originalName("_topen");
|
||||
} else if (Token::simpleMatch(tok, "_tsopen_s (")) {
|
||||
tok->str("_sopen_s");
|
||||
tok->originalName("_tsopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tfopen (")) {
|
||||
tok->str("fopen");
|
||||
tok->originalName("_tfopen");
|
||||
} else if (Token::simpleMatch(tok, "_tfopen_s (")) {
|
||||
tok->str("fopen_s");
|
||||
tok->originalName("_tfopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tfreopen (")) {
|
||||
tok->str("_wfreopen");
|
||||
tok->originalName("_tfreopen");
|
||||
} else if (Token::simpleMatch(tok, "_tfreopen_s (")) {
|
||||
tok->str("_wfreopen_s");
|
||||
tok->originalName("_tfreopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tcscat (")) {
|
||||
tok->str("strcat");
|
||||
tok->originalName("_tcscat");
|
||||
} else if (Token::simpleMatch(tok, "_tcschr (")) {
|
||||
tok->str("strchr");
|
||||
tok->originalName("_tcschr");
|
||||
} else if (Token::simpleMatch(tok, "_tcscmp (")) {
|
||||
tok->str("strcmp");
|
||||
tok->originalName("_tcscmp");
|
||||
} else if (Token::simpleMatch(tok, "_tcsdup (")) {
|
||||
tok->str("strdup");
|
||||
tok->originalName("_tcsdup");
|
||||
} else if (Token::simpleMatch(tok, "_tcscpy (")) {
|
||||
tok->str("strcpy");
|
||||
tok->originalName("_tcscpy");
|
||||
} else if (Token::simpleMatch(tok, "_tcslen (")) {
|
||||
tok->str("strlen");
|
||||
tok->originalName("_tcslen");
|
||||
} else if (Token::simpleMatch(tok, "_tcsncat (")) {
|
||||
tok->str("strncat");
|
||||
tok->originalName("_tcscat");
|
||||
} else if (Token::simpleMatch(tok, "_tcsncpy (")) {
|
||||
tok->str("strncpy");
|
||||
tok->originalName("_tcsncpy");
|
||||
} else if (Token::simpleMatch(tok, "_tcsnlen (")) {
|
||||
tok->str("strnlen");
|
||||
tok->originalName("_tcslen");
|
||||
} else if (Token::simpleMatch(tok, "_tcsrchr (")) {
|
||||
tok->str("strrchr");
|
||||
tok->originalName("_tcsrchr");
|
||||
} else if (Token::simpleMatch(tok, "_tcsstr (")) {
|
||||
tok->str("strstr");
|
||||
tok->originalName("_tcsstr");
|
||||
} else if (Token::simpleMatch(tok, "_tcstok (")) {
|
||||
tok->str("strtok");
|
||||
tok->originalName("_tcstok");
|
||||
} else if (Token::simpleMatch(tok, "_ftprintf (")) {
|
||||
tok->str("fprintf");
|
||||
tok->originalName("_ftprintf");
|
||||
|
@ -9619,30 +9645,60 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
|
|||
} else if (_settings->platformType == Settings::Win32W ||
|
||||
_settings->platformType == Settings::Win64) {
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "_tcscat (")) {
|
||||
if (Token::simpleMatch(tok, "_topen (")) {
|
||||
tok->str("_wopen");
|
||||
tok->originalName("_topen");
|
||||
} else if (Token::simpleMatch(tok, "_tsfopen_s (")) {
|
||||
tok->str("_wsopen_s");
|
||||
tok->originalName("_tsopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tfopen (")) {
|
||||
tok->str("_wfopen");
|
||||
tok->originalName("_tfopen");
|
||||
} else if (Token::simpleMatch(tok, "_tfopen_s (")) {
|
||||
tok->str("_wfopen_s");
|
||||
tok->originalName("_tfopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tfreopen (")) {
|
||||
tok->str("_wfreopen");
|
||||
tok->originalName("_tfreopen");
|
||||
} else if (Token::simpleMatch(tok, "_tfreopen_s (")) {
|
||||
tok->str("_wfreopen_s");
|
||||
tok->originalName("_tfreopen_s");
|
||||
} else if (Token::simpleMatch(tok, "_tcscat (")) {
|
||||
tok->str("wcscat");
|
||||
tok->originalName("_tcscat");
|
||||
} else if (Token::simpleMatch(tok, "_tcschr (")) {
|
||||
tok->str("wcschr");
|
||||
tok->originalName("_tcschr");
|
||||
} else if (Token::simpleMatch(tok, "_tcscmp (")) {
|
||||
tok->str("wcscmp");
|
||||
tok->originalName("_tcscmp");
|
||||
} else if (Token::simpleMatch(tok, "_tcscpy (")) {
|
||||
tok->str("wcscpy");
|
||||
tok->originalName("_tcscpy");
|
||||
} else if (Token::simpleMatch(tok, "_tcsdup (")) {
|
||||
tok->str("wcsdup");
|
||||
tok->originalName("_tcsdup");
|
||||
} else if (Token::simpleMatch(tok, "_tcslen (")) {
|
||||
tok->str("wcslen");
|
||||
tok->originalName("_tcslen");
|
||||
} else if (Token::simpleMatch(tok, "_tcsncat (")) {
|
||||
tok->str("wcsncat");
|
||||
tok->originalName("_tcsncat");
|
||||
} else if (Token::simpleMatch(tok, "_tcsncpy (")) {
|
||||
tok->str("wcsncpy");
|
||||
tok->originalName("_tcsncpy");
|
||||
} else if (Token::simpleMatch(tok, "_tcsnlen (")) {
|
||||
tok->str("wcsnlen");
|
||||
tok->originalName("_tcsnlen");
|
||||
} else if (Token::simpleMatch(tok, "_tcsrchr (")) {
|
||||
tok->str("wcsrchr");
|
||||
tok->originalName("_tcsrchr");
|
||||
} else if (Token::simpleMatch(tok, "_tcsstr (")) {
|
||||
tok->str("wcsstr");
|
||||
tok->originalName("_tcsstr");
|
||||
} else if (Token::simpleMatch(tok, "_tcstok (")) {
|
||||
tok->str("wcstok");
|
||||
tok->originalName("_tcstok");
|
||||
} else if (Token::simpleMatch(tok, "_ftprintf (")) {
|
||||
tok->str("fwprintf");
|
||||
tok->originalName("_ftprintf");
|
||||
|
|
132
test/testio.cpp
132
test/testio.cpp
|
@ -139,12 +139,96 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _wfopen(name, L\"r\");\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfopen(name, _T(\"r\"));\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfopen(name, _T(\"r\"));\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _wfopen_s(&f, name, L\"r\");\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _tfopen_s(&f, name, _T(\"r\"));\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _tfopen_s(&f, name, _T(\"r\"));\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" rewind(f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = fopen(name, \"r+\");\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _wfopen(name, L\"r+\");\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfopen(name, _T(\"r+\"));\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfopen(name, _T(\"r+\"));\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _wfopen_s(&f, name, L\"r+\");\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _tfopen_s(&f, name, _T(\"r+\"));\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" _tfopen_s(&f, name, _T(\"r+\"));\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// Write mode
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = fopen(name, \"w\");\n"
|
||||
|
@ -192,14 +276,6 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = fopen(name, \"a\");\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
" clearerr(f);\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Read operation on a file that was opened only for writing.\n", errout.str());
|
||||
|
||||
// freopen and tmpfile
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = freopen(name, \"r\", f);\n"
|
||||
|
@ -207,6 +283,42 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _wfreopen(name, L\"r\", f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfreopen(name, _T(\"r\"), f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfreopen(name, _T(\"r\"), f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _wfreopen_s(&f, name, L\"r\", f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfreopen_s(&f, name, _T(\"r\"), f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = _tfreopen_s(&f, name, _T(\"r\"), f);\n"
|
||||
" fwrite(buffer, 5, 6, f);\n"
|
||||
"}", false, false, Settings::Win32W);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Write operation on a file that was opened only for reading.\n", errout.str());
|
||||
|
||||
// Crash tests
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" f = fopen(name, mode);\n" // No assertion failure (#3830)
|
||||
|
@ -250,11 +362,13 @@ private:
|
|||
" clearerr(f);\n"
|
||||
" fread(buffer, 5, 6, f);\n"
|
||||
" ungetc('a', f);\n"
|
||||
" ungetwc(L'a', f);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Used file that is not opened.\n"
|
||||
"[test.cpp:4]: (error) Used file that is not opened.\n"
|
||||
"[test.cpp:5]: (error) Used file that is not opened.\n"
|
||||
"[test.cpp:6]: (error) Used file that is not opened.\n", errout.str());
|
||||
"[test.cpp:6]: (error) Used file that is not opened.\n"
|
||||
"[test.cpp:7]: (error) Used file that is not opened.\n", errout.str());
|
||||
|
||||
check("void foo(FILE*& f) {\n"
|
||||
" if(!ferror(f)) {\n"
|
||||
|
|
Loading…
Reference in New Issue