diff options
author | David Blaikie <dblaikie@gmail.com> | 2014-09-15 17:30:56 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2014-09-15 17:30:56 +0000 |
commit | 11f8a943bfafd445f4fbd3e126b0f88f7d039f47 (patch) | |
tree | 339e1ce0dad5e63154f74fc95f0450eab7fdc233 /clang/lib/Frontend | |
parent | 8f45c9cc6232e5b841bc92b7f2ea9a792574c317 (diff) | |
download | bcm5719-llvm-11f8a943bfafd445f4fbd3e126b0f88f7d039f47.tar.gz bcm5719-llvm-11f8a943bfafd445f4fbd3e126b0f88f7d039f47.zip |
Fix memory leak of raw_ostreams in LogDiagnosticPrinter handling.
This is another case of conditional ownership (in this case a raw
reference, plus a boolean to indicate whether the referenced object
should be deleted). While it's not ideal, I prefer to make the ownership
explicit with a unique_ptr than using a boolean flag (though it does
make the reference and the unique_ptr redundant in the sense that they
both refer to the same memory). At some point we might write a reusable
conditional ownership pointer (a stateful custom deleter for a unique_ptr
may be appropriate).
Based on a patch from a patch by Anton Yartsev.
llvm-svn: 217791
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Frontend/LogDiagnosticPrinter.cpp | 16 |
2 files changed, 12 insertions, 18 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index ec4817d61fa..395d85f7740 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -135,27 +135,27 @@ static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags) { std::error_code EC; - bool OwnsStream = false; + std::unique_ptr<raw_ostream> StreamOwner; raw_ostream *OS = &llvm::errs(); if (DiagOpts->DiagnosticLogFile != "-") { // Create the output stream. - llvm::raw_fd_ostream *FileOS(new llvm::raw_fd_ostream( + auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( DiagOpts->DiagnosticLogFile, EC, - llvm::sys::fs::F_Append | llvm::sys::fs::F_Text)); + llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); if (EC) { Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) << DiagOpts->DiagnosticLogFile << EC.message(); } else { FileOS->SetUnbuffered(); FileOS->SetUseAtomicWrites(true); - OS = FileOS; - OwnsStream = true; + OS = FileOS.get(); + StreamOwner = std::move(FileOS); } } // Chain in the diagnostic client which will log the diagnostics. - LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, - OwnsStream); + LogDiagnosticPrinter *Logger = + new LogDiagnosticPrinter(*OS, DiagOpts, std::move(StreamOwner)); if (CodeGenOpts) Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); diff --git a/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/clang/lib/Frontend/LogDiagnosticPrinter.cpp index 19539e0a5eb..c2dcd1be313 100644 --- a/clang/lib/Frontend/LogDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/LogDiagnosticPrinter.cpp @@ -18,17 +18,11 @@ using namespace clang; using namespace markup; -LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os, - DiagnosticOptions *diags, - bool _OwnsOutputStream) - : OS(os), LangOpts(nullptr), DiagOpts(diags), - OwnsOutputStream(_OwnsOutputStream) { -} - -LogDiagnosticPrinter::~LogDiagnosticPrinter() { - if (OwnsOutputStream) - delete &OS; -} +LogDiagnosticPrinter::LogDiagnosticPrinter( + raw_ostream &os, DiagnosticOptions *diags, + std::unique_ptr<raw_ostream> StreamOwner) + : OS(os), StreamOwner(std::move(StreamOwner)), LangOpts(nullptr), + DiagOpts(diags) {} static StringRef getLevelName(DiagnosticsEngine::Level Level) { switch (Level) { |