Index: llvm/trunk/include/llvm/AsmParser/Parser.h =================================================================== --- llvm/trunk/include/llvm/AsmParser/Parser.h +++ llvm/trunk/include/llvm/AsmParser/Parser.h @@ -36,10 +36,12 @@ /// \param Context Context in which to allocate globals info. /// \param Slots The optional slot mapping that will be initialized during /// parsing. -std::unique_ptr parseAssemblyFile(StringRef Filename, - SMDiagnostic &Error, - LLVMContext &Context, - SlotMapping *Slots = nullptr); +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! +std::unique_ptr +parseAssemblyFile(StringRef Filename, SMDiagnostic &Error, LLVMContext &Context, + SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true); /// The function is a secondary interface to the LLVM Assembly Parser. It parses /// an ASCII string that (presumably) contains LLVM Assembly code. It returns a @@ -52,10 +54,14 @@ /// \param Context Context in which to allocate globals info. /// \param Slots The optional slot mapping that will be initialized during /// parsing. +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! std::unique_ptr parseAssemblyString(StringRef AsmString, SMDiagnostic &Error, LLVMContext &Context, - SlotMapping *Slots = nullptr); + SlotMapping *Slots = nullptr, + bool UpgradeDebugInfo = true); /// parseAssemblyFile and parseAssemblyString are wrappers around this function. /// \brief Parse LLVM Assembly from a MemoryBuffer. @@ -63,9 +69,13 @@ /// \param Err Error result info. /// \param Slots The optional slot mapping that will be initialized during /// parsing. +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! std::unique_ptr parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots = nullptr); + SlotMapping *Slots = nullptr, + bool UpgradeDebugInfo = true); /// This function is the low-level interface to the LLVM Assembly Parser. /// This is kept as an independent function instead of being inlined into @@ -78,8 +88,12 @@ /// \param Slots The optional slot mapping that will be initialized during /// parsing. /// \return true on error. +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err, - SlotMapping *Slots = nullptr); + SlotMapping *Slots = nullptr, + bool UpgradeDebugInfo = true); /// Parse a type and a constant value in the given string. /// Index: llvm/trunk/include/llvm/IRReader/IRReader.h =================================================================== --- llvm/trunk/include/llvm/IRReader/IRReader.h +++ llvm/trunk/include/llvm/IRReader/IRReader.h @@ -37,14 +37,22 @@ /// If the given MemoryBuffer holds a bitcode image, return a Module /// for it. Otherwise, attempt to parse it as LLVM Assembly and return /// a Module for it. +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! std::unique_ptr parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, - LLVMContext &Context); + LLVMContext &Context, + bool UpgradeDebugInfo = true); /// If the given file holds a bitcode image, return a Module for it. /// Otherwise, attempt to parse it as LLVM Assembly and return a Module /// for it. +/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. +/// This option should only be set to false by llvm-as +/// for use inside the LLVM testuite! std::unique_ptr parseIRFile(StringRef Filename, SMDiagnostic &Err, - LLVMContext &Context); + LLVMContext &Context, + bool UpgradeDebugInfo = true); } #endif Index: llvm/trunk/lib/AsmParser/LLParser.h =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h +++ llvm/trunk/lib/AsmParser/LLParser.h @@ -139,11 +139,16 @@ std::map > ForwardRefAttrGroups; std::map NumberedAttrBuilders; + /// Only the llvm-as tool may set this to false to bypass + /// UpgradeDebuginfo so it can generate broken bitcode. + bool UpgradeDebugInfo; + public: LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M, - SlotMapping *Slots = nullptr) + SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true) : Context(M->getContext()), Lex(F, SM, Err, M->getContext()), M(M), - Slots(Slots), BlockAddressPFS(nullptr) {} + Slots(Slots), BlockAddressPFS(nullptr), + UpgradeDebugInfo(UpgradeDebugInfo) {} bool Run(); bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots); Index: llvm/trunk/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp +++ llvm/trunk/lib/AsmParser/LLParser.cpp @@ -237,7 +237,8 @@ } } - UpgradeDebugInfo(*M); + if (UpgradeDebugInfo) + llvm::UpgradeDebugInfo(*M); UpgradeModuleFlags(*M); Index: llvm/trunk/lib/AsmParser/Parser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/Parser.cpp +++ llvm/trunk/lib/AsmParser/Parser.cpp @@ -23,22 +23,21 @@ using namespace llvm; bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err, - SlotMapping *Slots) { + SlotMapping *Slots, bool UpgradeDebugInfo) { SourceMgr SM; std::unique_ptr Buf = MemoryBuffer::getMemBuffer(F); SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); - return LLParser(F.getBuffer(), SM, Err, &M, Slots).Run(); + return LLParser(F.getBuffer(), SM, Err, &M, Slots, UpgradeDebugInfo).Run(); } -std::unique_ptr llvm::parseAssembly(MemoryBufferRef F, - SMDiagnostic &Err, - LLVMContext &Context, - SlotMapping *Slots) { +std::unique_ptr +llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, + SlotMapping *Slots, bool UpgradeDebugInfo) { std::unique_ptr M = make_unique(F.getBufferIdentifier(), Context); - if (parseAssemblyInto(F, *M, Err, Slots)) + if (parseAssemblyInto(F, *M, Err, Slots, UpgradeDebugInfo)) return nullptr; return M; @@ -47,7 +46,8 @@ std::unique_ptr llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots) { + SlotMapping *Slots, + bool UpgradeDebugInfo) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -56,15 +56,17 @@ return nullptr; } - return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots); + return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, + UpgradeDebugInfo); } std::unique_ptr llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots) { + SlotMapping *Slots, + bool UpgradeDebugInfo) { MemoryBufferRef F(AsmString, ""); - return parseAssembly(F, Err, Context, Slots); + return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo); } Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, Index: llvm/trunk/lib/IR/AutoUpgrade.cpp =================================================================== --- llvm/trunk/lib/IR/AutoUpgrade.cpp +++ llvm/trunk/lib/IR/AutoUpgrade.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include @@ -2358,15 +2359,26 @@ /// info. Return true if module is modified. bool llvm::UpgradeDebugInfo(Module &M) { unsigned Version = getDebugMetadataVersionFromModule(M); - if (Version == DEBUG_METADATA_VERSION) - return false; - - bool RetCode = StripDebugInfo(M); - if (RetCode) { + if (Version == DEBUG_METADATA_VERSION) { + bool BrokenDebugInfo = false; + if (verifyModule(M, &llvm::errs(), &BrokenDebugInfo)) + report_fatal_error("Broken module found, compilation aborted!"); + if (!BrokenDebugInfo) + // Everything is ok. + return false; + else { + // Diagnose malformed debug info. + DiagnosticInfoIgnoringInvalidDebugMetadata Diag(M); + M.getContext().diagnose(Diag); + } + } + bool Modified = StripDebugInfo(M); + if (Modified && Version != DEBUG_METADATA_VERSION) { + // Diagnose a version mismatch. DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version); M.getContext().diagnose(DiagVersion); } - return RetCode; + return Modified; } bool llvm::UpgradeModuleFlags(Module &M) { Index: llvm/trunk/lib/IR/DebugInfo.cpp =================================================================== --- llvm/trunk/lib/IR/DebugInfo.cpp +++ llvm/trunk/lib/IR/DebugInfo.cpp @@ -290,7 +290,7 @@ bool llvm::stripDebugInfo(Function &F) { bool Changed = false; - if (F.getSubprogram()) { + if (F.getMetadata(LLVMContext::MD_dbg)) { Changed = true; F.setSubprogram(nullptr); } Index: llvm/trunk/lib/IR/Metadata.cpp =================================================================== --- llvm/trunk/lib/IR/Metadata.cpp +++ llvm/trunk/lib/IR/Metadata.cpp @@ -1431,7 +1431,6 @@ MDNode *GlobalObject::getMetadata(unsigned KindID) const { SmallVector MDs; getMetadata(KindID, MDs); - assert(MDs.size() <= 1 && "Expected at most one metadata attachment"); if (MDs.empty()) return nullptr; return MDs[0]; Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -4684,19 +4684,8 @@ HasErrors |= !V->verify(F); HasErrors |= !V->verify(); - if (FatalErrors) { - if (HasErrors) - report_fatal_error("Broken module found, compilation aborted!"); - assert(!V->hasBrokenDebugInfo() && "Module contains invalid debug info"); - } - - // Strip broken debug info. - if (V->hasBrokenDebugInfo()) { - DiagnosticInfoIgnoringInvalidDebugMetadata DiagInvalid(M); - M.getContext().diagnose(DiagInvalid); - if (!StripDebugInfo(M)) - report_fatal_error("Failed to strip malformed debug info"); - } + if (FatalErrors && (HasErrors || V->hasBrokenDebugInfo())) + report_fatal_error("Broken module found, compilation aborted!"); return false; } @@ -4999,19 +4988,9 @@ PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) { auto Res = AM.getResult(M); - if (FatalErrors) { - if (Res.IRBroken) - report_fatal_error("Broken module found, compilation aborted!"); - assert(!Res.DebugInfoBroken && "Module contains invalid debug info"); - } + if (FatalErrors && (Res.IRBroken || Res.DebugInfoBroken)) + report_fatal_error("Broken module found, compilation aborted!"); - // Strip broken debug info. - if (Res.DebugInfoBroken) { - DiagnosticInfoIgnoringInvalidDebugMetadata DiagInvalid(M); - M.getContext().diagnose(DiagInvalid); - if (!StripDebugInfo(M)) - report_fatal_error("Failed to strip malformed debug info"); - } return PreservedAnalyses::all(); } Index: llvm/trunk/lib/IRReader/IRReader.cpp =================================================================== --- llvm/trunk/lib/IRReader/IRReader.cpp +++ llvm/trunk/lib/IRReader/IRReader.cpp @@ -68,7 +68,8 @@ } std::unique_ptr llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, - LLVMContext &Context) { + LLVMContext &Context, + bool UpgradeDebugInfo) { NamedRegionTimer T(TimeIRParsingName, TimeIRParsingDescription, TimeIRParsingGroupName, TimeIRParsingGroupDescription, TimePassesIsEnabled); @@ -86,11 +87,12 @@ return std::move(ModuleOrErr.get()); } - return parseAssembly(Buffer, Err, Context); + return parseAssembly(Buffer, Err, Context, nullptr, UpgradeDebugInfo); } std::unique_ptr llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err, - LLVMContext &Context) { + LLVMContext &Context, + bool UpgradeDebugInfo) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -99,7 +101,8 @@ return nullptr; } - return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context); + return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context, + UpgradeDebugInfo); } //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -83,16 +83,6 @@ #endif cl::Hidden); -cl::opt LTOStripInvalidDebugInfo( - "lto-strip-invalid-debug-info", - cl::desc("Strip invalid debug info metadata during LTO instead of aborting."), -#ifdef NDEBUG - cl::init(true), -#else - cl::init(false), -#endif - cl::Hidden); - cl::opt LTORemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), @@ -495,8 +485,7 @@ HasVerifiedInput = true; bool BrokenDebugInfo = false; - if (verifyModule(*MergedModule, &dbgs(), - LTOStripInvalidDebugInfo ? &BrokenDebugInfo : nullptr)) + if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo)) report_fatal_error("Broken module found, compilation aborted!"); if (BrokenDebugInfo) { emitWarning("Invalid debug info found, debug info will be stripped"); Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -63,7 +63,6 @@ extern cl::opt LTODiscardValueNames; extern cl::opt LTORemarksFilename; extern cl::opt LTOPassRemarksWithHotness; -extern cl::opt LTOStripInvalidDebugInfo; } namespace { @@ -158,8 +157,7 @@ /// Verify the module and strip broken debug info. static void verifyLoadedModule(Module &TheModule) { bool BrokenDebugInfo = false; - if (verifyModule(TheModule, &dbgs(), - LTOStripInvalidDebugInfo ? &BrokenDebugInfo : nullptr)) + if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo)) report_fatal_error("Broken module found, compilation aborted!"); if (BrokenDebugInfo) { TheModule.getContext().diagnose(ThinLTODiagnosticInfo( Index: llvm/trunk/test/Analysis/GlobalsModRef/pr12351.ll =================================================================== --- llvm/trunk/test/Analysis/GlobalsModRef/pr12351.ll +++ llvm/trunk/test/Analysis/GlobalsModRef/pr12351.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s +; RUN: opt < %s -basicaa -globals-aa -gvn -S -disable-verify | FileCheck %s declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) define void @foo(i8* %x, i8* %y) { Index: llvm/trunk/test/DebugInfo/Generic/invalid.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/invalid.ll +++ llvm/trunk/test/DebugInfo/Generic/invalid.ll @@ -1,4 +1,4 @@ -; RUN: not opt -verify %s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output %s 2>&1 | FileCheck %s ; Make sure we emit this diagnostic only once (which means we don't visit the ; same DISubprogram twice. @@ -6,6 +6,7 @@ ; CHECK-NEXT: !3 = distinct !DISubprogram(name: "patatino", scope: null, isLocal: false, isDefinition: true, isOptimized: false) ; CHECK-NOT: subprogram definitions must have a compile unit ; CHECK-NOT: !3 = distinct !DISubprogram(name: "patatino", scope: null, isLocal: false, isDefinition: true, isOptimized: false) +; CHECK: warning: ignoring invalid debug info define void @tinkywinky() !dbg !3 { ret void } Index: llvm/trunk/test/DebugInfo/Generic/location-verifier.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/location-verifier.ll +++ llvm/trunk/test/DebugInfo/Generic/location-verifier.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as -disable-output -verify-debug-info < %s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output -verify-debug-info -o - < %s 2>&1 | FileCheck %s ; ModuleID = 'test.c' target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.10.0" @@ -30,3 +30,4 @@ ; An old-style DILocation should not pass verify. ; CHECK: invalid !dbg metadata attachment !13 = !{i32 2, i32 2, !4, null} +; CHECK: warning: ignoring invalid debug info Index: llvm/trunk/test/DebugInfo/Generic/piece-verifier.ll =================================================================== --- llvm/trunk/test/DebugInfo/Generic/piece-verifier.ll +++ llvm/trunk/test/DebugInfo/Generic/piece-verifier.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as -disable-output < %s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output < %s 2>&1 | FileCheck %s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.9.0" @@ -53,3 +53,4 @@ ; CHECK-NEXT: !DIExpression({{[0-9]+}}, 64, 32, {{[0-9]+}}) ; CHECK-NOT: invalid expression !27 = !DIExpression(DW_OP_LLVM_fragment, 64, 32, DW_OP_deref) +; CHECK: warning: ignoring invalid debug info Index: llvm/trunk/test/DebugInfo/pr34186.ll =================================================================== --- llvm/trunk/test/DebugInfo/pr34186.ll +++ llvm/trunk/test/DebugInfo/pr34186.ll @@ -5,9 +5,11 @@ ; alternative is that of keeping a map of visited GVs, which has non trivial ; memory usage consequences on large testcases, or when LTO is the mode of ; operation. -; RUN: not llc %s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output %s -o - 2>&1 | FileCheck %s ; CHECK: missing global variable type ; CHECK: missing global variable type +; CHECK-NOT: missing global variable type +; CHECK: warning: ignoring invalid debug info !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!63, !64} Index: llvm/trunk/test/DebugInfo/pr34672.ll =================================================================== --- llvm/trunk/test/DebugInfo/pr34672.ll +++ llvm/trunk/test/DebugInfo/pr34672.ll @@ -1,4 +1,4 @@ -; RUN: not opt -verify %s 2>&1 | FileCheck %s +; RUN: opt -verify %s 2>&1 | FileCheck %s ; CHECK: invalid type ref ; CHECK-NOT: invalid type ref Index: llvm/trunk/test/LTO/X86/strip-debug-info-no-call-loc.ll =================================================================== --- llvm/trunk/test/LTO/X86/strip-debug-info-no-call-loc.ll +++ llvm/trunk/test/LTO/X86/strip-debug-info-no-call-loc.ll @@ -1,6 +1,5 @@ ; RUN: llvm-as %s -disable-verify -o %t.bc -; RUN: llvm-lto -lto-strip-invalid-debug-info=true \ -; RUN: -exported-symbol f -exported-symbol _f \ +; RUN: llvm-lto -exported-symbol f -exported-symbol _f \ ; RUN: -o %t.o %t.bc 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; RUN: llvm-nm %t.o | FileCheck %s @@ -8,7 +7,7 @@ ; Check that missing debug locations on inlinable calls are a ; recoverable error. -; CHECK-WARN: Invalid debug info found, debug info will be stripped +; CHECK-WARN: warning{{.*}} ignoring invalid debug info ; CHECK: {{f$}} target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx" Index: llvm/trunk/test/LTO/X86/strip-debug-info.ll =================================================================== --- llvm/trunk/test/LTO/X86/strip-debug-info.ll +++ llvm/trunk/test/LTO/X86/strip-debug-info.ll @@ -1,52 +1,32 @@ ; RUN: llvm-as -disable-verify %s -o %t.bc ; ---- Full LTO --------------------------------------------- -; RUN: not llvm-lto -lto-strip-invalid-debug-info=false \ -; RUN: -o %t.o %t.bc 2>&1 | \ -; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR -; RUN: llvm-lto -lto-strip-invalid-debug-info=true \ +; RUN: llvm-lto \ ; RUN: -exported-symbol foo -exported-symbol _foo \ ; RUN: -o %t.o %t.bc 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; RUN: llvm-nm %t.o | FileCheck %s ; ---- Thin LTO (codegen only) ------------------------------ -; RUN: not llvm-lto -thinlto -thinlto-action=codegen \ -; RUN: -lto-strip-invalid-debug-info=false \ -; RUN: %t.bc -disable-verify 2>&1 | \ -; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR ; RUN: llvm-lto -thinlto -thinlto-action=codegen \ -; RUN: -lto-strip-invalid-debug-info=true \ ; RUN: %t.bc -disable-verify 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; ---- Thin LTO (optimize, strip main file) ----------------- ; RUN: opt -disable-verify -module-summary %s -o %t.bc ; RUN: opt -disable-verify -module-summary %S/Inputs/strip-debug-info-bar.ll \ ; RUN: -o %t2.bc -; RUN: not llvm-lto -thinlto -thinlto-action=run \ -; RUN: -lto-strip-invalid-debug-info=false \ -; RUN: %t.bc -disable-verify 2>&1 | \ -; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR ; RUN: llvm-lto -thinlto -thinlto-action=run \ -; RUN: -lto-strip-invalid-debug-info=true \ ; RUN: %t.bc -disable-verify 2>&1 | \ ; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN ; ---- Thin LTO (optimize, strip imported file) ------------- ; RUN: opt -disable-verify -strip-debug -module-summary %t.bc -o %t-stripped.bc ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t-stripped.bc %t2.bc -; RUN: not llvm-lto -thinlto -thinlto-action=import \ -; RUN: -thinlto-index=%t.index.bc \ -; RUN: -lto-strip-invalid-debug-info=false \ -; RUN: -exported-symbol foo -exported-symbol _foo \ -; RUN: %t-stripped.bc -disable-verify 2>&1 | \ -; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR ; RUN: llvm-lto -thinlto -thinlto-action=import \ -; RUN: -lto-strip-invalid-debug-info=true \ ; RUN: -thinlto-index=%t.index.bc \ ; RUN: -exported-symbol foo -exported-symbol _foo \ ; RUN: %t-stripped.bc -disable-verify 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: warning{{.*}} ignoring invalid debug info ; CHECK-WARN-NOT: Broken module found ; CHECK: foo target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" Index: llvm/trunk/test/Verifier/DILocation-parents.ll =================================================================== --- llvm/trunk/test/Verifier/DILocation-parents.ll +++ llvm/trunk/test/Verifier/DILocation-parents.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as %s -o - 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output %s -o - 2>&1 | FileCheck %s source_filename = "t.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" @@ -17,6 +17,8 @@ ret void, !dbg !9 } +; CHECK: warning: ignoring invalid debug info + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!2, !3} Index: llvm/trunk/test/Verifier/DISubprogram.ll =================================================================== --- llvm/trunk/test/Verifier/DISubprogram.ll +++ llvm/trunk/test/Verifier/DISubprogram.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S <%s 2>&1| FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s define void @f() !dbg !14 { ret void @@ -12,6 +12,7 @@ !8 = distinct !DICompileUnit(language: DW_LANG_Swift, producer: "clang", file: !2, emissionKind: 2) ; CHECK: invalid thrown type +; CHECK: warning: ignoring invalid debug info !13 = !{!14} !14 = distinct !DISubprogram(name: "f", scope: !1, file: !2, line: 1, type: !3, isLocal: true, Index: llvm/trunk/test/Verifier/callsite-dbgloc.ll =================================================================== --- llvm/trunk/test/Verifier/callsite-dbgloc.ll +++ llvm/trunk/test/Verifier/callsite-dbgloc.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as %s -o %t 2>&1 | FileCheck %s +; RUN: llvm-as %s -o %t 2>&1 | FileCheck %s ; Created and then edited from ; extern void i(); ; void h() { i(); } @@ -39,6 +39,8 @@ attributes #0 = { nounwind ssp uwtable } +; CHECK: warning: ignoring invalid debug info + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5} !llvm.ident = !{!6} Index: llvm/trunk/test/Verifier/dbg-difile-crash.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-difile-crash.ll +++ llvm/trunk/test/Verifier/dbg-difile-crash.ll @@ -1,6 +1,6 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify -; CHECK-NEXT: invalid file +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s +; CHECK: invalid file +; CHECK: warning: ignoring invalid debug info define void @blah() !dbg !3 { ret void Index: llvm/trunk/test/Verifier/dbg-invalid-compileunit.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-invalid-compileunit.ll +++ llvm/trunk/test/Verifier/dbg-invalid-compileunit.ll @@ -1,5 +1,5 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s +; CHECK: warning: ignoring invalid debug info !llvm.module.flags = !{!0} !llvm.dbg.cu = !{!1} Index: llvm/trunk/test/Verifier/dbg-invalid-named-metadata.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-invalid-named-metadata.ll +++ llvm/trunk/test/Verifier/dbg-invalid-named-metadata.ll @@ -1,5 +1,5 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s +; CHECK: warning: ignoring invalid debug info !llvm.module.flags = !{!0} !llvm.dbg.the_dbg_namespace_is_reserved = !{} Index: llvm/trunk/test/Verifier/dbg-invalid-retaintypes.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-invalid-retaintypes.ll +++ llvm/trunk/test/Verifier/dbg-invalid-retaintypes.ll @@ -1,5 +1,5 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s +; CHECK: warning: ignoring invalid debug info !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3} Index: llvm/trunk/test/Verifier/dbg-line-without-file.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-line-without-file.ll +++ llvm/trunk/test/Verifier/dbg-line-without-file.ll @@ -1,6 +1,6 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: line specified with no file +; CHECK: warning: ignoring invalid debug info define void @foo() !dbg !3 { ret void Index: llvm/trunk/test/Verifier/dbg-null-retained-type.ll =================================================================== --- llvm/trunk/test/Verifier/dbg-null-retained-type.ll +++ llvm/trunk/test/Verifier/dbg-null-retained-type.ll @@ -1,6 +1,6 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: assembly parsed, but does not verify -; CHECK-NEXT: invalid retained type +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s +; CHECK: invalid retained type +; CHECK: warning: ignoring invalid debug info !llvm.module.flags = !{!0} !0 = !{i32 2, !"Debug Info Version", i32 3} Index: llvm/trunk/test/Verifier/dbg.ll =================================================================== --- llvm/trunk/test/Verifier/dbg.ll +++ llvm/trunk/test/Verifier/dbg.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s define void @foo() { entry: @@ -14,6 +14,7 @@ ; CHECK-NEXT: ![[LOC]] = !{} } +; CHECK: warning: ignoring invalid debug info !llvm.module.flags = !{!0} !0 = !{i32 2, !"Debug Info Version", i32 3} !1 = distinct !DISubprogram() Index: llvm/trunk/test/Verifier/diglobalvariable.ll =================================================================== --- llvm/trunk/test/Verifier/diglobalvariable.ll +++ llvm/trunk/test/Verifier/diglobalvariable.ll @@ -1,4 +1,4 @@ -; RUN: not opt -S <%s 2>&1| FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s ; CHECK: !dbg attachment of global variable must be a DIGlobalVariableExpression @g = common global i32 0, align 4, !dbg !0 @@ -12,3 +12,4 @@ !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) !6 = !{i32 2, !"Dwarf Version", i32 4} !7 = !{i32 2, !"Debug Info Version", i32 3} +; CHECK: warning: ignoring invalid debug info Index: llvm/trunk/test/Verifier/fnarg-debuginfo.ll =================================================================== --- llvm/trunk/test/Verifier/fnarg-debuginfo.ll +++ llvm/trunk/test/Verifier/fnarg-debuginfo.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s declare void @llvm.dbg.declare(metadata, metadata, metadata) declare void @llvm.dbg.value(metadata, i64, metadata, metadata) @@ -12,6 +12,8 @@ ret void, !dbg !6 } +; CHECK: warning: ignoring invalid debug info + !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!7, !8} Index: llvm/trunk/test/Verifier/fragment.ll =================================================================== --- llvm/trunk/test/Verifier/fragment.ll +++ llvm/trunk/test/Verifier/fragment.ll @@ -1,9 +1,10 @@ -; RUN: not opt -S <%s 2>&1| FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s ; CHECK: fragment is larger than or outside of variable ; CHECK: !DIGlobalVariableExpression(var: ![[VAR:[0-9]+]], ; CHECK-SAME: expr: !DIExpression(DW_OP_LLVM_fragment, 0, 64)) ; CHECK: ![[VAR]] = !DIGlobalVariable(name: "g" +; CHECK: warning: ignoring invalid debug info @g = common global i32 0, align 4, !dbg !0 Index: llvm/trunk/test/Verifier/func-dbg.ll =================================================================== --- llvm/trunk/test/Verifier/func-dbg.ll +++ llvm/trunk/test/Verifier/func-dbg.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s define i32 @foo() !dbg !4 { entry: @@ -11,6 +11,7 @@ ret i32 0, !dbg !6 } +; CHECK: warning: ignoring invalid debug info !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!7, !8} Index: llvm/trunk/test/Verifier/llvm.dbg.declare-address.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.declare-address.ll +++ llvm/trunk/test/Verifier/llvm.dbg.declare-address.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.declare intrinsic address/value ; CHECK-NEXT: call void @llvm.dbg.declare({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/llvm.dbg.declare-expression.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.declare-expression.ll +++ llvm/trunk/test/Verifier/llvm.dbg.declare-expression.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.declare intrinsic expression ; CHECK-NEXT: call void @llvm.dbg.declare({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/llvm.dbg.declare-variable.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.declare-variable.ll +++ llvm/trunk/test/Verifier/llvm.dbg.declare-variable.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.declare intrinsic variable ; CHECK-NEXT: call void @llvm.dbg.declare({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/llvm.dbg.value-expression.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.value-expression.ll +++ llvm/trunk/test/Verifier/llvm.dbg.value-expression.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.value intrinsic expression ; CHECK-NEXT: call void @llvm.dbg.value({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/llvm.dbg.value-value.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.value-value.ll +++ llvm/trunk/test/Verifier/llvm.dbg.value-value.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.value intrinsic address/value ; CHECK-NEXT: call void @llvm.dbg.value({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/llvm.dbg.value-variable.ll =================================================================== --- llvm/trunk/test/Verifier/llvm.dbg.value-variable.ll +++ llvm/trunk/test/Verifier/llvm.dbg.value-variable.ll @@ -1,7 +1,8 @@ -; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s ; CHECK: invalid llvm.dbg.value intrinsic variable ; CHECK-NEXT: call void @llvm.dbg.value({{.*}}) ; CHECK-NEXT: !"" +; CHECK: warning: ignoring invalid debug info define void @foo(i32 %a) { entry: Index: llvm/trunk/test/Verifier/metadata-function-dbg.ll =================================================================== --- llvm/trunk/test/Verifier/metadata-function-dbg.ll +++ llvm/trunk/test/Verifier/metadata-function-dbg.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as %s -disable-output 2>&1 | FileCheck %s +; RUN: llvm-as %s -disable-output 2>&1 | FileCheck %s ; CHECK: function declaration may not have a !dbg attachment declare !dbg !4 void @f1() @@ -26,6 +26,7 @@ unreachable } +; CHECK: warning: ignoring invalid debug info !llvm.module.flags = !{!0} !0 = !{i32 2, !"Debug Info Version", i32 3} Index: llvm/trunk/test/Verifier/pr34325.ll =================================================================== --- llvm/trunk/test/Verifier/pr34325.ll +++ llvm/trunk/test/Verifier/pr34325.ll @@ -1,6 +1,7 @@ -; RUN: not opt -verify %s 2>&1 | FileCheck %s +; RUN: llvm-as -disable-output %s 2>&1 | FileCheck %s ; CHECK: invalid type ref +; CHECK: warning: ignoring invalid debug info @bar = global i64 0, align 8, !dbg !0 Index: llvm/trunk/test/Verifier/tbaa.ll =================================================================== --- llvm/trunk/test/Verifier/tbaa.ll +++ llvm/trunk/test/Verifier/tbaa.ll @@ -1,5 +1,5 @@ ; RUN: not llvm-as < %s 2>&1 | FileCheck %s -; RUN: llvm-as -disable-verify < %s 2>&1 | opt -verify -S | FileCheck %s --check-prefix=STRIP +; RUN: llvm-as -disable-verify < %s | opt -verify -S | FileCheck %s --check-prefix=STRIP ; STRIP-NOT: tbaa ; STRIP: @f_0 Index: llvm/trunk/tools/llvm-as/llvm-as.cpp =================================================================== --- llvm/trunk/tools/llvm-as/llvm-as.cpp +++ llvm/trunk/tools/llvm-as/llvm-as.cpp @@ -97,7 +97,8 @@ // Parse the file now... SMDiagnostic Err; - std::unique_ptr M = parseAssemblyFile(InputFilename, Err, Context); + std::unique_ptr M = + parseAssemblyFile(InputFilename, Err, Context, nullptr, !DisableVerify); if (!M.get()) { Err.print(argv[0], errs()); return 1; Index: llvm/trunk/tools/opt/opt.cpp =================================================================== --- llvm/trunk/tools/opt/opt.cpp +++ llvm/trunk/tools/opt/opt.cpp @@ -444,7 +444,8 @@ } // Load the input module... - std::unique_ptr M = parseIRFile(InputFilename, Err, Context); + std::unique_ptr M = + parseIRFile(InputFilename, Err, Context, !NoVerify); if (!M) { Err.print(argv[0], errs()); Index: llvm/trunk/unittests/IR/VerifierTest.cpp =================================================================== --- llvm/trunk/unittests/IR/VerifierTest.cpp +++ llvm/trunk/unittests/IR/VerifierTest.cpp @@ -17,7 +17,6 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "gtest/gtest.h" @@ -149,7 +148,7 @@ "have external or weak linkage!")); } -TEST(VerifierTest, StripInvalidDebugInfo) { +TEST(VerifierTest, DetectInvalidDebugInfo) { { LLVMContext C; Module M("M", C); @@ -164,13 +163,6 @@ NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); NMD->addOperand(File); EXPECT_TRUE(verifyModule(M)); - - ModulePassManager MPM(true); - MPM.addPass(VerifierPass(false)); - ModuleAnalysisManager MAM(true); - MAM.registerPass([&] { return VerifierAnalysis(); }); - MPM.run(M, MAM); - EXPECT_FALSE(verifyModule(M)); } { LLVMContext C; @@ -195,36 +187,8 @@ // Now break it by not listing the CU at all. M.eraseNamedMetadata(M.getOrInsertNamedMetadata("llvm.dbg.cu")); EXPECT_TRUE(verifyModule(M)); - - ModulePassManager MPM(true); - MPM.addPass(VerifierPass(false)); - ModuleAnalysisManager MAM(true); - MAM.registerPass([&] { return VerifierAnalysis(); }); - MPM.run(M, MAM); - EXPECT_FALSE(verifyModule(M)); } } -TEST(VerifierTest, StripInvalidDebugInfoLegacy) { - LLVMContext C; - Module M("M", C); - DIBuilder DIB(M); - DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"), - "unittest", false, "", 0); - DIB.finalize(); - EXPECT_FALSE(verifyModule(M)); - - // Now break it. - auto *File = DIB.createFile("not-a-CU.f", "."); - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); - NMD->addOperand(File); - EXPECT_TRUE(verifyModule(M)); - - legacy::PassManager Passes; - Passes.add(createVerifierPass(false)); - Passes.run(M); - EXPECT_FALSE(verifyModule(M)); -} - } // end anonymous namespace } // end namespace llvm