diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 910c12445..1824f25de 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -176,12 +176,20 @@ void CheckIO::checkFileUsage() operation = Filepointer::OPEN; } else if ((tok->str() == "rewind" || tok->str() == "fseek" || tok->str() == "fsetpos" || tok->str() == "fflush") || (windows && tok->str() == "_fseeki64")) { - if (_settings->isEnabled("portability") && Token::simpleMatch(tok, "fflush ( stdin )")) - fflushOnInputStreamError(tok, tok->strAt(2)); - else { + if (_settings->isEnabled("portability") && tok->str() == "fflush") { fileTok = tok->tokAt(2); - operation = Filepointer::POSITIONING; + + if (fileTok && fileTok->str() == "stdin") + fflushOnInputStreamError(tok, fileTok->str()); + else { + Filepointer& f = filepointers[fileTok->varId()]; + if (f.mode == READ_MODE) + fflushOnInputStreamError(tok, fileTok->str()); + } } + + fileTok = tok->tokAt(2); + operation = Filepointer::POSITIONING; } 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" || diff --git a/test/testio.cpp b/test/testio.cpp index a597e2cb5..5204c9ed8 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -589,6 +589,23 @@ private: " fflush(stdout);\n" "}", false, true); ASSERT_EQUALS("", errout.str()); + + check("void foo(FILE*& f) {\n" + " f = fopen(path, \"r\");\n" + " fflush(f);\n" + "}", false, true); + ASSERT_EQUALS("[test.cpp:3]: (portability) fflush() called on input stream 'f' may result in undefined behaviour on non-linux systems.\n", errout.str()); + + check("void foo(FILE*& f) {\n" + " f = fopen(path, \"w\");\n" + " fflush(f);\n" + "}", false, true); + ASSERT_EQUALS("", errout.str()); + + check("void foo(FILE*& f) {\n" + " fflush(f);\n" + "}", false, true); + ASSERT_EQUALS("", errout.str()); }