Index: include/clang/Driver/Compilation.h =================================================================== --- include/clang/Driver/Compilation.h +++ include/clang/Driver/Compilation.h @@ -122,6 +122,9 @@ /// Whether an error during the parsing of the input args. bool ContainsError; + /// Whether to keep temporary files regardless of -save-temps. + bool ForceKeepTempFiles = false; + public: Compilation(const Driver &D, const ToolChain &DefaultToolChain, llvm::opt::InputArgList *Args, Index: lib/Driver/Compilation.cpp =================================================================== --- lib/Driver/Compilation.cpp +++ lib/Driver/Compilation.cpp @@ -45,6 +45,11 @@ } Compilation::~Compilation() { + // Remove temporary files. This must be done before arguments are freed, as + // the file names might be derived from the input arguments. + if (!TheDriver.isSaveTempsEnabled() && !ForceKeepTempFiles) + CleanupFileList(TempFiles); + delete TranslatedArgs; delete Args; @@ -245,6 +250,10 @@ AllActions.clear(); Jobs.clear(); + // Remove temporary files. + if (!TheDriver.isSaveTempsEnabled() && !ForceKeepTempFiles) + CleanupFileList(TempFiles); + // Clear temporary/results file lists. TempFiles.clear(); ResultFiles.clear(); @@ -262,6 +271,9 @@ // Redirect stdout/stderr to /dev/null. Redirects = {None, {""}, {""}}; + + // Temporary files added by diagnostics should be kept. + ForceKeepTempFiles = true; } StringRef Compilation::getSysRoot() const { Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1243,9 +1243,6 @@ // If any of the preprocessing commands failed, clean up and exit. if (!FailingCommands.empty()) { - if (!isSaveTempsEnabled()) - C.CleanupFileList(C.getTempFiles(), true); - Diag(clang::diag::note_drv_command_failed_diag_msg) << "Error generating preprocessed source(s)."; return; @@ -1362,9 +1359,6 @@ C.ExecuteJobs(C.getJobs(), FailingCommands); - // Remove temp files. - C.CleanupFileList(C.getTempFiles()); - // If the command succeeded, we are done. if (FailingCommands.empty()) return 0;