Index: lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- lib/LTO/ThinLTOCodeGenerator.cpp +++ lib/LTO/ThinLTOCodeGenerator.cpp @@ -25,9 +25,11 @@ #include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" +#include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/LTO/LTO.h" #include "llvm/Linker/Linker.h" @@ -62,6 +64,7 @@ extern cl::opt LTODiscardValueNames; extern cl::opt LTORemarksFilename; extern cl::opt LTOPassRemarksWithHotness; +extern cl::opt LTOStripInvalidDebugInfo; } namespace { @@ -142,6 +145,17 @@ report_fatal_error("renameModuleForThinLTO failed"); } +namespace { +class ThinLTODiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; +public: + ThinLTODiagnosticInfo(const Twine &DiagMsg, + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {} + void print(DiagnosticPrinter &DP) const override { DP << Msg; } +}; +} + static std::unique_ptr loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context, bool Lazy, bool IsImporting) { @@ -159,6 +173,17 @@ }); report_fatal_error("Can't load module, abort."); } + + // Verify the module. + bool BrokenDebugInfo = false; + if (verifyModule(*ModuleOrErr.get(), &dbgs(), + LTOStripInvalidDebugInfo ? &BrokenDebugInfo : nullptr)) + report_fatal_error("Broken module found, compilation aborted!"); + if (BrokenDebugInfo) { + Context.diagnose(ThinLTODiagnosticInfo( + "Invalid debug info found, debug info will be stripped", DS_Warning)); + StripDebugInfo(*ModuleOrErr.get()); + } return std::move(ModuleOrErr.get()); } Index: test/LTO/X86/strip-debug-info.ll =================================================================== --- test/LTO/X86/strip-debug-info.ll +++ test/LTO/X86/strip-debug-info.ll @@ -6,9 +6,19 @@ ; RUN: -o %t.o %S/Inputs/strip-debug-info.bc 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; RUN: llvm-nm %t.o | FileCheck %s +; RUN: not llvm-lto -thinlto -thinlto-action=run \ +; RUN: -lto-strip-invalid-debug-info=false \ +; RUN: %S/Inputs/strip-debug-info.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR +; RUN: not llvm-lto -thinlto -thinlto-action=run \ +; RUN: -lto-strip-invalid-debug-info=true \ +; RUN: -exported-symbol foo -exported-symbol _foo \ +; RUN: %S/Inputs/strip-debug-info.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; CHECK-ERR: Broken module found, compilation aborted ; CHECK-WARN: Invalid debug info found, debug info will be stripped +; CHECK-WARN-NOT: Broken module found ; CHECK: foo define void @foo() { ret void