Skip to content

Commit 969864c

Browse files
fixup! Fix #1473: warn when fclose() is used as a while loop condition
1 parent 5fa3789 commit 969864c

2 files changed

Lines changed: 33 additions & 9 deletions

File tree

lib/checkio.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,25 @@ void CheckIO::checkFileUsage()
247247
operation = Filepointer::Operation::CLOSE;
248248

249249
// #1473 Check if fclose is in a while loop condition
250-
const Token* tmp = tok->astParent();
251-
const Token* loopTok = nullptr;
252-
while (tmp) {
253-
if (Token::simpleMatch(tmp->previous(), "while (")) {
254-
loopTok = tmp->previous();
255-
break;
250+
if (fileTok) {
251+
const Token* tmp = tok->astParent();
252+
const Token* loopTok = nullptr;
253+
while (tmp) {
254+
if (Token::simpleMatch(tmp->previous(), "while (")) {
255+
loopTok = tmp->previous();
256+
break;
257+
}
258+
tmp = tmp->astParent();
259+
}
260+
if (loopTok) {
261+
const Token* bodyStart = loopTok->linkAt(1)->next();
262+
const Token* bodyEnd = bodyStart->link();
263+
264+
// Do not trigger a warning if the loop always exits or if the file is opened again in the loop.
265+
if (!isReturnScope(bodyEnd, mSettings->library) && Token::findmatch(bodyStart, "%var% = fopen|freopen", bodyEnd, fileTok->varId()) == nullptr)
266+
useClosedFileError(tok);
256267
}
257-
tmp = tmp->astParent();
258268
}
259-
if (loopTok)
260-
useClosedFileError(tok);
261269
} else if (whitelist.find(tok->str()) != whitelist.end()) {
262270
fileTok = tok->tokAt(2);
263271
if ((tok->str() == "ungetc" || tok->str() == "ungetwc") && fileTok)

test/testio.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,22 @@ class TestIO : public TestFixture {
546546
"}");
547547
ASSERT_EQUALS("[test.cpp:3:12]: (error) Used file that is not opened. [useClosedFile]\n", errout_str());
548548

549+
check("void foo() {\n"
550+
" FILE *a = fopen(\"aa\", \"r\");\n"
551+
" while (fclose(a)) {\n"
552+
" break;\n"
553+
" }\n"
554+
"}");
555+
ASSERT_EQUALS("", errout_str());
556+
557+
check("void foo() {\n"
558+
" FILE *a = fopen(\"aa\", \"r\");\n"
559+
" while (fclose(a)) {\n"
560+
" a = fopen(\"aa\", \"r\");\n"
561+
" }\n"
562+
"}");
563+
ASSERT_EQUALS("", errout_str());
564+
549565
// #6823
550566
check("void foo() {\n"
551567
" FILE f[2];\n"

0 commit comments

Comments
 (0)