--- /dev/null
+# Test multithreaded error reporting.
+
+RUN: not llvm-profdata merge -j 4 -o %t.profdata \
+RUN: %S/Inputs/counter-mismatch-1.proftext \
+RUN: %S/Inputs/counter-mismatch-2.proftext \
+RUN: %S/Inputs/counter-mismatch-3.proftext \
+RUN: %S/Inputs/counter-mismatch-4.proftext \
+RUN: 2>&1 | FileCheck %s
+
+CHECK: Function basic block count change detected (counter mismatch)
enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
-static void exitWithError(const Twine &Message, StringRef Whence = "",
- StringRef Hint = "") {
+static void exitWithError(Twine Message, std::string Whence = "",
+ std::string Hint = "") {
errs() << "error: ";
if (!Whence.empty())
errs() << Whence << ": ";
std::mutex Lock;
InstrProfWriter Writer;
Error Err;
- StringRef ErrWhence;
+ std::string ErrWhence;
std::mutex &ErrLock;
SmallSet<instrprof_error, 4> &WriterErrorCodes;
if (WC->Err)
return;
+ // Copy the filename, because llvm::ThreadPool copied the input "const
+ // WeightedFile &" by value, making a reference to the filename within it
+ // invalid outside of this packaged task.
WC->ErrWhence = Input.Filename;
auto ReaderOrErr = InstrProfReader::create(Input.Filename);
/// Merge the \p Src writer context into \p Dst.
static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) {
+ // If we've already seen a hard error, continuing with the merge would
+ // clobber it.
+ if (Dst->Err || Src->Err)
+ return;
+
bool Reported = false;
Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer), [&](Error E) {
if (Reported) {