Index: cfe/trunk/include/clang/Driver/Compilation.h =================================================================== --- cfe/trunk/include/clang/Driver/Compilation.h +++ cfe/trunk/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: cfe/trunk/lib/Driver/Compilation.cpp =================================================================== --- cfe/trunk/lib/Driver/Compilation.cpp +++ cfe/trunk/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: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/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; Index: clang-tools-extra/trunk/test/clang-tidy/pr37091.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/pr37091.cpp +++ clang-tools-extra/trunk/test/clang-tidy/pr37091.cpp @@ -0,0 +1,10 @@ +// REQUIRES: shell +// RUN: rm -rf %t +// RUN: mkdir -p %t + +// This is a reproducer for PR37091. +// +// Verify that no temporary files are left behind by the clang-tidy invocation. + +// RUN: env TMPDIR=%t TEMP=%t TMP=%t clang-tidy %s -- --target=mips64 +// RUN: rmdir %t