llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Jon Roelofs (jroelofs) <details> <summary>Changes</summary> rdar://176327788 --- Full diff: https://github.com/llvm/llvm-project/pull/197600.diff 4 Files Affected: - (modified) clang/include/clang/Driver/Compilation.h (+11-1) - (modified) clang/include/clang/Driver/Job.h (+8) - (modified) clang/lib/Driver/Driver.cpp (+19-4) - (added) clang/test/Driver/crash-report-multi-arch.c (+86) ``````````diff diff --git a/clang/include/clang/Driver/Compilation.h b/clang/include/clang/Driver/Compilation.h index 26781fc676832..4ad2dc34a1f85 100644 --- a/clang/include/clang/Driver/Compilation.h +++ b/clang/include/clang/Driver/Compilation.h @@ -126,6 +126,10 @@ class Compilation { /// Whether to keep temporary files regardless of -save-temps. bool ForceKeepTempFiles = false; + /// The bound architecture currently being built, if any. Set around + /// ConstructJob calls so addCommand can stamp it onto each new Command. + StringRef CurrentBoundArch; + public: Compilation(const Driver &D, const ToolChain &DefaultToolChain, llvm::opt::InputArgList *Args, @@ -211,7 +215,13 @@ class Compilation { JobList &getJobs() { return Jobs; } const JobList &getJobs() const { return Jobs; } - void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); } + void addCommand(std::unique_ptr<Command> Cmd) { + Cmd->setBoundArch(CurrentBoundArch); + Jobs.addJob(std::move(Cmd)); + } + + StringRef getCurrentBoundArch() const { return CurrentBoundArch; } + void setCurrentBoundArch(StringRef Arch) { CurrentBoundArch = Arch; } llvm::opt::ArgStringList &getTempFiles() { return TempFiles; } const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; } diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h index c5934498d4241..116254f79ae6f 100644 --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -150,6 +150,10 @@ class Command { /// Information on executable run provided by OS. mutable std::optional<llvm::sys::ProcessStatistics> ProcStat; + /// The bound architecture for this command (e.g. "arm64", "x86_64"). + /// Non-empty only for Darwin multi-arch builds. + std::string BoundArch; + /// When a response file is needed, we try to put most arguments in an /// exclusive file, while others remains as regular command line arguments. /// This functions fills a vector with the regular command line arguments, @@ -190,6 +194,10 @@ class Command { /// getCreator - Return the Tool which caused the creation of this job. const Tool &getCreator() const { return Creator; } + /// Return the bound architecture for this command, if any. + StringRef getBoundArch() const { return BoundArch; } + void setBoundArch(StringRef Arch) { BoundArch = std::string(Arch); } + /// Returns the kind of response file supported by the current invocation. const ResponseFileSupport &getResponseFileSupport() { return ResponseSupport; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ed3ddd130d6c7..a06044953daec 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -75,6 +75,7 @@ #include "clang/ScalableStaticAnalysisFramework/SSAFForceLinker.h" // IWYU pragma: keep #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -2139,10 +2140,17 @@ void Driver::generateCompilationDiagnostics( } } if (ArchNames.size() > 1) { - Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating preprocessed source(s) - cannot generate " - "preprocessed source with multiple -arch options."; - return; + // Build a reproducer only for the bound arch that crashed. + StringRef FailingArch = Cmd.getBoundArch(); + if (FailingArch.empty()) { + Diag(clang::diag::note_drv_command_failed_diag_msg) + << "Error generating preprocessed source(s) - cannot generate " + "preprocessed source with multiple -arch options."; + return; + } + C.getArgs().eraseArg(options::OPT_arch); + C.getArgs().AddJoinedArg(nullptr, getOpts().getOption(options::OPT_arch), + FailingArch); } // If we only have IR inputs there's no need for preprocessing. @@ -6062,6 +6070,13 @@ InputInfoList Driver::BuildJobsForActionNoCache( Action::OffloadKind TargetDeviceOffloadKind) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); + // Track the bound arch for commands constructed in this scope so + // generateCompilationDiagnostics can identify the crashing arch. + StringRef SavedBoundArch = C.getCurrentBoundArch(); + C.setCurrentBoundArch(BoundArch); + auto RestoreBoundArch = + llvm::scope_exit([&] { C.setCurrentBoundArch(SavedBoundArch); }); + InputInfoList OffloadDependencesInputInfo; bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None; if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) { diff --git a/clang/test/Driver/crash-report-multi-arch.c b/clang/test/Driver/crash-report-multi-arch.c new file mode 100644 index 0000000000000..b12a50cd75b12 --- /dev/null +++ b/clang/test/Driver/crash-report-multi-arch.c @@ -0,0 +1,86 @@ +// RUN: rm -rf %t +// RUN: mkdir %t + +// Verify that crash diagnostics are generated for just the crashing arch when +// multiple -arch options are present, rather than bailing out entirely. + +// RUN: env CLANG_CRASH_DIAGNOSTICS_DIR=%t \ +// RUN: not %crash_opt %clang %s -arch arm64 -arch arm64e -arch x86_64 -fsyntax-only -DCRASH_x86_64 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH-x86_64 %s +// RUN: rm -f %t/crash-report-* + +// RUN: env CLANG_CRASH_DIAGNOSTICS_DIR=%t \ +// RUN: not %crash_opt %clang %s -arch arm64 -arch arm64e -arch x86_64 -fsyntax-only -DCRASH_arm64 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH-arm64 %s +// RUN: rm -f %t/crash-report-* + +// RUN: env CLANG_CRASH_DIAGNOSTICS_DIR=%t \ +// RUN: not %crash_opt %clang %s -arch arm64 -arch arm64e -arch x86_64 -fsyntax-only -DCRASH_arm64e 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH-arm64e %s +// RUN: rm -f %t/crash-report-* + +// If multiple arches crash, capture the reproducer for the first one. +// one in the list. +// RUN: env CLANG_CRASH_DIAGNOSTICS_DIR=%t \ +// RUN: not %crash_opt %clang %s -arch arm64 -arch arm64e -arch x86_64 -fsyntax-only -DCRASH_arm64 -DCRASH_arm64e 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH-arm64 %s +// RUN: rm -f %t/crash-report-* + +// Likewise for -gen-reproducer, the reproducer script should target the first arch. +// RUN: env CLANG_CRASH_DIAGNOSTICS_DIR=%t \ +// RUN: not %clang %s -arch arm64 -arch arm64e -fsyntax-only -gen-reproducer 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK %s +// RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH-arm64 %s + +// REQUIRES: crash-recovery, system-darwin +// REQUIRES: aarch64-registered-target, x86-registered-target + +// CHECK: Preprocessed source(s) and associated run script(s) are located at: +// CHECK-NEXT: note: diagnostic msg: {{.*}}crash-report-{{.*}}.c + +// CHECKSH-x86_64: # Crash reproducer +// CHECKSH-x86_64: "-cc1" +// CHECKSH-x86_64: "-triple" "x86_64{{[^"]*}}" +// CHECKSH-x86_64-NOT: "-triple" "arm64{{[^"]*}}" +// CHECKSH-x86_64-NOT: "-arch" "arm64" +// CHECKSH-x86_64-NOT: "-arch" "arm64e" + +// CHECKSH-arm64: # Crash reproducer +// CHECKSH-arm64: "-cc1" +// CHECKSH-arm64: "-triple" "arm64-{{[^"]*}}" +// CHECKSH-arm64-NOT: "-triple" "arm64e{{[^"]*}}" +// CHECKSH-arm64-NOT: "-triple" "x86_64{{[^"]*}}" +// CHECKSH-arm64-NOT: "-arch" "arm64e" +// CHECKSH-arm64-NOT: "-arch" "x86_64" + +// CHECKSH-arm64e: # Crash reproducer +// CHECKSH-arm64e: "-cc1" +// CHECKSH-arm64e: "-triple" "arm64e{{[^"]*}}" +// CHECKSH-arm64e-NOT: "-triple" "arm64-{{[^"]*}}" +// CHECKSH-arm64e-NOT: "-triple" "x86_64{{[^"]*}}" +// CHECKSH-arm64e-NOT: "-arch" "arm64" +// CHECKSH-arm64e-NOT: "-arch" "x86_64" + +#ifdef CRASH_x86_64 +# ifdef __x86_64__ +# pragma clang __debug crash +# endif +#endif + +#ifdef CRASH_arm64 +# if defined(__aarch64__) && !defined(__arm64e__) +# pragma clang __debug crash +# endif +#endif + +#ifdef CRASH_arm64e +# ifdef __arm64e__ +# pragma clang __debug crash +# endif +#endif + +int x; `````````` </details> https://github.com/llvm/llvm-project/pull/197600 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
