diff --git a/clang/include/clang/Driver/Compilation.h b/clang/include/clang/Driver/Compilation.h index 8c9990909ebb..fd88c3a63636 100644 --- a/clang/include/clang/Driver/Compilation.h +++ b/clang/include/clang/Driver/Compilation.h @@ -56,6 +56,10 @@ class Compilation { /// Result files which should be removed on failure. ArgStringList ResultFiles; + /// Result files which are generated correctly on failure, and which should + /// only be removed if we crash. + ArgStringList FailureResultFiles; + /// Redirection for stdout, stderr, etc. const llvm::sys::Path **Redirects; @@ -84,6 +88,10 @@ public: const ArgStringList &getResultFiles() const { return ResultFiles; } + const ArgStringList &getFailureResultFiles() const { + return FailureResultFiles; + } + /// getArgsForToolChain - Return the derived argument list for the /// tool chain \arg TC (or the default tool chain, if TC is not /// specified). @@ -106,6 +114,13 @@ public: return Name; } + /// addFailureResultFile - Add a file to remove if we crash, and returns its + /// argument. + const char *addFailureResultFile(const char *Name) { + FailureResultFiles.push_back(Name); + return Name; + } + /// CleanupFileList - Remove the files in the given list. /// /// \param IssueErrors - Report failures as errors. diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index feeeb049f55d..086e3a411f35 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -507,9 +507,14 @@ int Driver::ExecuteCompilation(const Compilation &C, return Res; // Otherwise, remove result files as well. - if (!C.getArgs().hasArg(options::OPT_save_temps)) + if (!C.getArgs().hasArg(options::OPT_save_temps)) { C.CleanupFileList(C.getResultFiles(), true); + // Failure result files are valid unless we crashed. + if (Res < 0) + C.CleanupFileList(C.getFailureResultFiles(), true); + } + // Print extra information about abnormal failures, if possible. // // This is ad-hoc, but we don't want to be excessively noisy. If the result diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 906f2ae0db7b..161001ccdbdc 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -218,11 +218,13 @@ void Clang::AddPreprocessingOptions(Compilation &C, DepFile = Output.getFilename(); } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) { DepFile = MF->getValue(Args); + C.addFailureResultFile(DepFile); } else if (A->getOption().matches(options::OPT_M) || A->getOption().matches(options::OPT_MM)) { DepFile = "-"; } else { DepFile = darwin::CC1::getDependencyFileName(Args, Inputs); + C.addFailureResultFile(DepFile); } CmdArgs.push_back("-dependency-file"); CmdArgs.push_back(DepFile); diff --git a/clang/test/Driver/crash-cleanup.c b/clang/test/Driver/crash-cleanup.c deleted file mode 100644 index b994bd85a306..000000000000 --- a/clang/test/Driver/crash-cleanup.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: not %clang -o %t.o -MMD -MF %t.d %s -// RUN: test ! -f %t.o -// RUN: test ! -f %t.d -// REQUIRES: shell -// REQUIRES: crash-recovery - -// XFAIL: * - -#pragma clang __debug crash diff --git a/clang/test/Driver/output-file-cleanup.c b/clang/test/Driver/output-file-cleanup.c new file mode 100644 index 000000000000..b4745e224733 --- /dev/null +++ b/clang/test/Driver/output-file-cleanup.c @@ -0,0 +1,20 @@ +// RUN: touch %t.o +// RUN: not %clang -DCRASH -o %t.o -MMD -MF %t.d %s +// RUN: test ! -f %t.o +// RUN: test ! -f %t.d + +// RUN: touch %t.o +// RUN: not %clang -o %t.o -MMD -MF %t.d %s +// RUN: test ! -f %t.o +// RUN: test -f %t.d + +// REQUIRES: shell +// REQUIRES: crash-recovery + +// XFAIL: darwin + +#ifdef CRASH +#pragma clang __debug crash +#else +invalid C code +#endif