diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index cb07f3f356e..70c15cea861 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -43,6 +43,7 @@ #endif #include +#include #include #include // EXIT_SUCCESS and EXIT_FAILURE #include @@ -75,7 +76,19 @@ CppCheckExecutor::CppCheckExecutor() CppCheckExecutor::~CppCheckExecutor() { - delete mErrorOutput; + if (mErrorOutput) { + try + { + mErrorOutput->close(); + } + catch (const std::ios_base::failure&) + { + // TODO report error + assert(false); + } + + delete mErrorOutput; + } } bool CppCheckExecutor::parseFromArgs(Settings &settings, int argc, const char* const argv[]) @@ -266,7 +279,9 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) mLatestProgressOutputTime = std::time(nullptr); if (!settings.outputFile.empty()) { - mErrorOutput = new std::ofstream(settings.outputFile); + mErrorOutput = new std::ofstream(); + mErrorOutput->exceptions(std::ios_base::failbit | std::ios_base::badbit); + mErrorOutput->open(settings.outputFile); } if (settings.xml) { diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 480907a599f..886720b490d 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -76,7 +76,9 @@ static bool executeCommand(std::string exe, std::vector args, std:: output = process.readAllStandardOutput().toStdString(); if (redirect.compare(0,3,"2> ") == 0) { - std::ofstream fout(redirect.substr(3)); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(redirect.substr(3)); fout << process.readAllStandardError().toStdString(); } return process.exitCode() == 0; diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index b3b6a394724..ddaf177ca38 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -23,13 +23,27 @@ #include "utils.h" #include +#include #include #include #include // IWYU pragma: keep +AnalyzerInformation::AnalyzerInformation() +{ + mOutputStream.exceptions(std::ios_base::failbit | std::ios_base::badbit); +} + AnalyzerInformation::~AnalyzerInformation() { - close(); + try + { + close(); + } + catch (const std::ios_base::failure&) + { + // TODO: Report error + assert(false); + } } static std::string getFilename(const std::string &fullpath) @@ -49,7 +63,9 @@ void AnalyzerInformation::writeFilesTxt(const std::string &buildDir, const std:: std::map fileCount; const std::string filesTxt(buildDir + "/files.txt"); - std::ofstream fout(filesTxt); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(filesTxt); for (const std::string &f : sourcefiles) { const std::string afile = getFilename(f); fout << afile << ".a" << (++fileCount[afile]) << "::" << Path::simplifyPath(Path::fromNativeSeparators(f)) << '\n'; @@ -65,7 +81,6 @@ void AnalyzerInformation::writeFilesTxt(const std::string &buildDir, const std:: void AnalyzerInformation::close() { - mAnalyzerInfoFile.clear(); if (mOutputStream.is_open()) { mOutputStream << "\n"; mOutputStream.close(); @@ -139,12 +154,8 @@ bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::st return false; mOutputStream.open(mAnalyzerInfoFile); - if (mOutputStream.is_open()) { - mOutputStream << "\n"; - mOutputStream << "\n"; - } else { - mAnalyzerInfoFile.clear(); - } + mOutputStream << "\n"; + mOutputStream << "\n"; return true; } diff --git a/lib/analyzerinfo.h b/lib/analyzerinfo.h index 340d08f5e07..1f5319b5e9c 100644 --- a/lib/analyzerinfo.h +++ b/lib/analyzerinfo.h @@ -49,6 +49,7 @@ class ErrorMessage; */ class CPPCHECKLIB AnalyzerInformation { public: + AnalyzerInformation(); ~AnalyzerInformation(); static void writeFilesTxt(const std::string &buildDir, const std::list &sourcefiles, const std::string &userDefines, const std::list &fileSettings); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 9be785315b0..7ce2089cc7d 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -276,11 +276,16 @@ static void createDumpFile(const Settings& settings, dumpFile = getDumpFileName(settings, filename); fdump.open(dumpFile); + + // TODO: Technically, exceptions are allowed on the file so this is always false, + // TODO: but the function is not aware of that as this function is not the owner of the file if (!fdump.is_open()) return; { - std::ofstream fout(getCtuInfoFileName(dumpFile)); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(getCtuInfoFileName(dumpFile)); } std::string language; @@ -396,7 +401,9 @@ CppCheck::CppCheck(ErrorLogger &errorLogger, , mTooManyConfigs(false) , mSimplify(true) , mExecuteCommand(std::move(executeCommand)) -{} +{ + mPlistFile.exceptions(std::ios_base::failbit | std::ios_base::badbit); +} CppCheck::~CppCheck() { @@ -408,7 +415,16 @@ CppCheck::~CppCheck() if (mPlistFile.is_open()) { mPlistFile << ErrorLogger::plistFooter(); - mPlistFile.close(); + + try + { + mPlistFile.close(); + } + catch (const std::ios_base::failure&) + { + // TODO report error + assert(false); + } } } @@ -504,7 +520,9 @@ unsigned int CppCheck::check(const std::string &path) const std::string args2 = "-fsyntax-only -Xclang -ast-dump -fno-color-diagnostics " + flags + path; const std::string redirect2 = analyzerInfo.empty() ? std::string("2>&1") : ("2> " + clangStderr); if (!mSettings.buildDir.empty()) { - std::ofstream fout(clangcmd); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(clangcmd); fout << exe << " " << args2 << " " << redirect2 << std::endl; } else if (mSettings.verbose && !mSettings.quiet) { mErrorLogger.reportOut(exe + " " + args2); @@ -535,7 +553,9 @@ unsigned int CppCheck::check(const std::string &path) } if (!mSettings.buildDir.empty()) { - std::ofstream fout(clangAst); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(clangAst); fout << output2 << std::endl; } @@ -555,6 +575,7 @@ unsigned int CppCheck::check(const std::string &path) // create dumpfile std::ofstream fdump; + fdump.exceptions(std::ios_base::failbit | std::ios_base::badbit); std::string dumpFile; createDumpFile(mSettings, path, fdump, dumpFile); if (fdump.is_open()) { @@ -773,6 +794,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string // write dump file xml prolog std::ofstream fdump; + fdump.exceptions(std::ios_base::failbit | std::ios_base::badbit); std::string dumpFile; createDumpFile(mSettings, filename, fdump, dumpFile); if (fdump.is_open()) { @@ -1422,7 +1444,9 @@ void CppCheck::executeAddons(const std::vector& files) if (files.size() >= 2 || endsWith(files[0], ".ctu-info")) { fileList = Path::getPathFromFilename(files[0]) + FILELIST; - std::ofstream fout(fileList); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(fileList); for (const std::string& f: files) fout << f << std::endl; } @@ -1681,7 +1705,10 @@ void CppCheck::analyseClangTidy(const ImportProject::FileSettings &fileSettings) if (!mSettings.buildDir.empty()) { const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, fileSettings.filename, emptyString); - std::ofstream fcmd(analyzerInfoFile + ".clang-tidy-cmd"); + + std::ofstream fcmd; + fcmd.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fcmd.open(analyzerInfoFile + ".clang-tidy-cmd"); fcmd << istr.str(); } diff --git a/lib/summaries.cpp b/lib/summaries.cpp index 7ad8a0b1b01..b2a9cda312a 100644 --- a/lib/summaries.cpp +++ b/lib/summaries.cpp @@ -86,7 +86,9 @@ std::string Summaries::create(const Tokenizer *tokenizer, const std::string &cfg const std::string::size_type pos = filename.rfind(".a"); if (pos != std::string::npos) { filename[pos+1] = 's'; - std::ofstream fout(filename); + std::ofstream fout; + fout.exceptions(std::ios_base::failbit | std::ios_base::badbit); + fout.open(filename); fout << ostr.str(); } } diff --git a/test/helpers.cpp b/test/helpers.cpp index 9c86d7320b6..cc21854fc51 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -54,9 +54,9 @@ ScopedFile::ScopedFile(std::string name, const std::string &content, std::string #endif } - std::ofstream of(mFullPath); - if (!of.is_open()) - throw std::runtime_error("ScopedFile(" + mFullPath + ") - could not open file"); + std::ofstream of; + of.exceptions(std::ios_base::failbit | std::ios_base::badbit); + of.open(mFullPath); of << content; } diff --git a/tools/dmake.cpp b/tools/dmake.cpp index e2571fa8764..8828d3d80f3 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -214,8 +214,10 @@ static int write_vcxproj(const std::string &proj_name, const std::function