/// \param Context Context in which to allocate globals info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-std::unique_ptr<Module> 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<Module>
+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
/// \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<Module> 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.
/// \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<Module> 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
/// \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.
///
/// 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<Module> 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<Module> parseIRFile(StringRef Filename, SMDiagnostic &Err,
- LLVMContext &Context);
+ LLVMContext &Context,
+ bool UpgradeDebugInfo = true);
}
#endif
}
}
- UpgradeDebugInfo(*M);
+ if (UpgradeDebugInfo)
+ llvm::UpgradeDebugInfo(*M);
UpgradeModuleFlags(*M);
std::map<Value*, std::vector<unsigned> > ForwardRefAttrGroups;
std::map<unsigned, AttrBuilder> 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);
using namespace llvm;
bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err,
- SlotMapping *Slots) {
+ SlotMapping *Slots, bool UpgradeDebugInfo) {
SourceMgr SM;
std::unique_ptr<MemoryBuffer> 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<Module> llvm::parseAssembly(MemoryBufferRef F,
- SMDiagnostic &Err,
- LLVMContext &Context,
- SlotMapping *Slots) {
+std::unique_ptr<Module>
+llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
+ SlotMapping *Slots, bool UpgradeDebugInfo) {
std::unique_ptr<Module> M =
make_unique<Module>(F.getBufferIdentifier(), Context);
- if (parseAssemblyInto(F, *M, Err, Slots))
+ if (parseAssemblyInto(F, *M, Err, Slots, UpgradeDebugInfo))
return nullptr;
return M;
std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
SMDiagnostic &Err,
LLVMContext &Context,
- SlotMapping *Slots) {
+ SlotMapping *Slots,
+ bool UpgradeDebugInfo) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = FileOrErr.getError()) {
return nullptr;
}
- return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots);
+ return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots,
+ UpgradeDebugInfo);
}
std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
SMDiagnostic &Err,
LLVMContext &Context,
- SlotMapping *Slots) {
+ SlotMapping *Slots,
+ bool UpgradeDebugInfo) {
MemoryBufferRef F(AsmString, "<string>");
- return parseAssembly(F, Err, Context, Slots);
+ return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo);
}
Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
#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 <cstring>
/// 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) {
bool llvm::stripDebugInfo(Function &F) {
bool Changed = false;
- if (F.getSubprogram()) {
+ if (F.getMetadata(LLVMContext::MD_dbg)) {
Changed = true;
F.setSubprogram(nullptr);
}
MDNode *GlobalObject::getMetadata(unsigned KindID) const {
SmallVector<MDNode *, 1> MDs;
getMetadata(KindID, MDs);
- assert(MDs.size() <= 1 && "Expected at most one metadata attachment");
if (MDs.empty())
return nullptr;
return MDs[0];
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;
}
PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
auto Res = AM.getResult<VerifierAnalysis>(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();
}
}
std::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ bool UpgradeDebugInfo) {
NamedRegionTimer T(TimeIRParsingName, TimeIRParsingDescription,
TimeIRParsingGroupName, TimeIRParsingGroupDescription,
TimePassesIsEnabled);
return std::move(ModuleOrErr.get());
}
- return parseAssembly(Buffer, Err, Context);
+ return parseAssembly(Buffer, Err, Context, nullptr, UpgradeDebugInfo);
}
std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ bool UpgradeDebugInfo) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = FileOrErr.getError()) {
return nullptr;
}
- return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context);
+ return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context,
+ UpgradeDebugInfo);
}
//===----------------------------------------------------------------------===//
#endif
cl::Hidden);
-cl::opt<bool> 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<std::string>
LTORemarksFilename("lto-pass-remarks-output",
cl::desc("Output filename for pass remarks"),
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");
extern cl::opt<bool> LTODiscardValueNames;
extern cl::opt<std::string> LTORemarksFilename;
extern cl::opt<bool> LTOPassRemarksWithHotness;
-extern cl::opt<bool> LTOStripInvalidDebugInfo;
}
namespace {
/// 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(
-; 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) {
-; 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.
; 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 }
-; 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"
; 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
-; 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"
; 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
; 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}
-; 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
; 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
; 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"
; 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"
-; 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"
ret void, !dbg !9
}
+; CHECK: warning: ignoring invalid debug info
+
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3}
-; 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
!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,
-; 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(); }
attributes #0 = { nounwind ssp uwtable }
+; CHECK: warning: ignoring invalid debug info
+
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!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
-; 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}
-; 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 = !{}
-; 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}
-; 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
-; 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}
-; 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:
; CHECK-NEXT: ![[LOC]] = !{}
}
+; CHECK: warning: ignoring invalid debug info
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DISubprogram()
-; 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
!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
-; 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)
ret void, !dbg !6
}
+; CHECK: warning: ignoring invalid debug info
+
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!7, !8}
-; 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
-; 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:
ret i32 0, !dbg !6
}
+; CHECK: warning: ignoring invalid debug info
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!7, !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:
-; 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:
-; 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:
-; 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:
-; 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:
-; 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:
-; 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()
unreachable
}
+; CHECK: warning: ignoring invalid debug info
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
-; 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
; 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
// Parse the file now...
SMDiagnostic Err;
- std::unique_ptr<Module> M = parseAssemblyFile(InputFilename, Err, Context);
+ std::unique_ptr<Module> M =
+ parseAssemblyFile(InputFilename, Err, Context, nullptr, !DisableVerify);
if (!M.get()) {
Err.print(argv[0], errs());
return 1;
}
// Load the input module...
- std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
+ std::unique_ptr<Module> M =
+ parseIRFile(InputFilename, Err, Context, !NoVerify);
if (!M) {
Err.print(argv[0], errs());
#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"
"have external or weak linkage!"));
}
-TEST(VerifierTest, StripInvalidDebugInfo) {
+TEST(VerifierTest, DetectInvalidDebugInfo) {
{
LLVMContext C;
Module M("M", C);
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;
// 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