Author: Alex Brachet Date: 2022-05-27T17:03:32Z New Revision: 4dc3893eeb47bef9298c34cdc993165af88721a5
URL: https://github.com/llvm/llvm-project/commit/4dc3893eeb47bef9298c34cdc993165af88721a5 DIFF: https://github.com/llvm/llvm-project/commit/4dc3893eeb47bef9298c34cdc993165af88721a5.diff LOG: Revert "[Clang] Extend -gen-reproducer flag" This reverts commit 684c080108766b4f112f172fed4a49059484614d. Added: Modified: clang/include/clang/Driver/Driver.h clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp clang/tools/driver/driver.cpp Removed: clang/test/Driver/emit-reproducer.c ################################################################################ diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 86eea9375f673..f0f294a669d98 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -276,6 +276,11 @@ class Driver { unsigned ProbePrecompiled : 1; public: + /// Force clang to emit reproducer for driver invocation. This is enabled + /// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable + /// or when using the -gen-reproducer driver flag. + unsigned GenReproducer : 1; + // getFinalPhase - Determine which compilation mode we are in and record // which option we used to determine the final phase. // TODO: Much of what getFinalPhase returns are not actually true compiler @@ -500,32 +505,6 @@ class Driver { StringRef AdditionalInformation = "", CompilationDiagnosticReport *GeneratedReport = nullptr); - enum class CommandStatus { - Crash = 1, - Error, - Ok, - }; - - enum class ReproLevel { - Off = 0, - OnCrash = static_cast<int>(CommandStatus::Crash), - OnError = static_cast<int>(CommandStatus::Error), - Always = static_cast<int>(CommandStatus::Ok), - }; - - bool maybeGenerateCompilationDiagnostics( - CommandStatus CS, ReproLevel Level, Compilation &C, - const Command &FailingCommand, StringRef AdditionalInformation = "", - CompilationDiagnosticReport *GeneratedReport = nullptr) { - if (static_cast<int>(CS) > static_cast<int>(Level)) - return false; - // Hack to ensure that diagnostic notes get emitted. - Diags.setLastDiagnosticIgnored(false); - generateCompilationDiagnostics(C, FailingCommand, AdditionalInformation, - GeneratedReport); - return true; - } - /// @} /// @name Helper Methods /// @{ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2a5e8bf27e353..e19baac5860aa 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -558,10 +558,7 @@ def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output"> def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, HelpText<"Emit ARC errors even if the migrator can fix them">, Flags<[CC1Option]>, MarshallingInfoFlag<FrontendOpts<"ARCMTMigrateEmitARCErrors">>; -def gen_reproducer_eq: Joined<["-"], "gen-reproducer=">, Flags<[NoArgumentUnused, CoreOption]>, - HelpText<"Emit reproducer on (option: off, crash (default), error, always)">; def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt, - Alias<gen_reproducer_eq>, AliasArgs<["always"]>, HelpText<"Auto-generates preprocessed source files and a reproduction script">; def gen_cdb_fragment_path: Separate<["-"], "gen-cdb-fragment-path">, InternalDebugOpt, HelpText<"Emit a compilation database fragment to the specified directory">; @@ -1400,7 +1397,6 @@ def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-cons def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">, Group<f_Group>; def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>, - Alias<gen_reproducer_eq>, AliasArgs<["off"]>, HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">; def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index aaef2e1ded327..94925568aec23 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -198,7 +198,8 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false), CCGenDiagnostics(false), CCPrintProcessStats(false), TargetTriple(TargetTriple), Saver(Alloc), CheckInputsExist(true), - ProbePrecompiled(true), SuppressMissingInputWarning(false) { + ProbePrecompiled(true), GenReproducer(false), + SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. if (!this->VFS) this->VFS = llvm::vfs::getRealFileSystem(); @@ -1216,6 +1217,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { CCCPrintBindings = Args.hasArg(options::OPT_ccc_print_bindings); if (const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name)) CCCGenericGCCName = A->getValue(); + GenReproducer = Args.hasFlag(options::OPT_gen_reproducer, + options::OPT_fno_crash_diagnostics, + !!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")); // Process -fproc-stat-report options. if (const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) { diff --git a/clang/test/Driver/emit-reproducer.c b/clang/test/Driver/emit-reproducer.c deleted file mode 100644 index f50171b7d9a9b..0000000000000 --- a/clang/test/Driver/emit-reproducer.c +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: rm -rf %t && mkdir %t - -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -gen-reproducer=crash 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -gen-reproducer=error 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -gen-reproducer=always 2>&1 | FileCheck %s -// RUN: not %clang -DFATAL %s -fcrash-diagnostics-dir=%t -gen-reproducer 2>&1 | FileCheck %s - -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -gen-reproducer=crash 2>&1 | FileCheck %s --check-prefix=NOT -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -gen-reproducer=error 2>&1 | FileCheck %s -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -gen-reproducer=always 2>&1 | FileCheck %s -// RUN: not %clang -DERROR %s -fcrash-diagnostics-dir=%t -gen-reproducer 2>&1 | FileCheck %s - -// RUN: %clang %s -fcrash-diagnostics-dir=%t -gen-reproducer=off 2>&1 | FileCheck %s --check-prefix=NOT --allow-empty -// RUN: %clang %s -fcrash-diagnostics-dir=%t -fno-crash-diagnostics 2>&1 | FileCheck %s --check-prefix=NOT --allow-empty -// RUN: %clang %s -fcrash-diagnostics-dir=%t 2>&1 | FileCheck %s --check-prefix=NOT --allow-empty -// RUN: %clang %s -fcrash-diagnostics-dir=%t -gen-reproducer=crash 2>&1 | FileCheck %s --check-prefix=NOT --allow-empty -// RUN: %clang %s -fcrash-diagnostics-dir=%t -gen-reproducer=error 2>&1 | FileCheck %s --check-prefix=NOT --allow-empty -// RUN: not %clang %s -fcrash-diagnostics-dir=%t -gen-reproducer=always 2>&1 | FileCheck %s -// RUN: not %clang %s -fcrash-diagnostics-dir=%t -gen-reproducer 2>&1 | FileCheck %s - -// RUN: not %clang $s -gen-reproducer=badvalue 2>&1 | FileCheck %s --check-prefix=BAD-VALUE -// BAD-VALUE: Unknown value for -gen-reproducer=: 'badvalue' - -// CHECK: note: diagnostic msg: {{.*}}emit-reproducer-{{.*}}.c -// NOT-NOT: note: diagnostic msg: {{.*}}emit-reproducer-{{.*}}.c - -#ifdef FATAL -#pragma clang __debug crash -#elif ERROR -int main -#else -int main() {} -#endif diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index c9aee57d92cf4..a7bfb07e002bf 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -482,37 +482,32 @@ int main(int Argc, const char **Argv) { } std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args)); - - Driver::ReproLevel ReproLevel = Driver::ReproLevel::OnCrash; - if (Arg *A = C->getArgs().getLastArg(options::OPT_gen_reproducer_eq)) { - auto Level = llvm::StringSwitch<Optional<Driver::ReproLevel>>(A->getValue()) - .Case("off", Driver::ReproLevel::Off) - .Case("crash", Driver::ReproLevel::OnCrash) - .Case("error", Driver::ReproLevel::OnError) - .Case("always", Driver::ReproLevel::Always) - .Default(None); - if (!Level) { - llvm::errs() << "Unknown value for " << A->getSpelling() << ": '" - << A->getValue() << "'\n"; - return 1; - } - ReproLevel = *Level; - } - if (!!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) - ReproLevel = Driver::ReproLevel::Always; - int Res = 1; bool IsCrash = false; - Driver::CommandStatus CommandStatus = Driver::CommandStatus::Ok; - // Pretend the first command failed if ReproStatus is Always. - const Command *FailingCommand = &*C->getJobs().begin(); if (C && !C->containsError()) { SmallVector<std::pair<int, const Command *>, 4> FailingCommands; Res = TheDriver.ExecuteCompilation(*C, FailingCommands); + // Force a crash to test the diagnostics. + if (TheDriver.GenReproducer) { + Diags.Report(diag::err_drv_force_crash) + << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"); + + // Pretend that every command failed. + FailingCommands.clear(); + for (const auto &J : C->getJobs()) + if (const Command *C = dyn_cast<Command>(&J)) + FailingCommands.push_back(std::make_pair(-1, C)); + + // Print the bug report message that would be printed if we did actually + // crash, but only if we're crashing due to FORCE_CLANG_DIAGNOSTICS_CRASH. + if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) + llvm::dbgs() << llvm::getBugReportMsg(); + } + for (const auto &P : FailingCommands) { int CommandRes = P.first; - FailingCommand = P.second; + const Command *FailingCommand = P.second; if (!Res) Res = CommandRes; @@ -531,21 +526,13 @@ int main(int Argc, const char **Argv) { // https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html IsCrash |= CommandRes > 128; #endif - CommandStatus = - IsCrash ? Driver::CommandStatus::Crash : Driver::CommandStatus::Error; - if (IsCrash) + if (IsCrash) { + TheDriver.generateCompilationDiagnostics(*C, *FailingCommand); break; + } } } - // Print the bug report message that would be printed if we did actually - // crash, but only if we're crashing due to FORCE_CLANG_DIAGNOSTICS_CRASH. - if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) - llvm::dbgs() << llvm::getBugReportMsg(); - if (TheDriver.maybeGenerateCompilationDiagnostics(CommandStatus, ReproLevel, - *C, *FailingCommand)) - Res = 1; - Diags.getClient()->finish(); if (!UseNewCC1Process && IsCrash) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits