diff --git a/llvm/include/llvm/AutoUpgrade.h b/llvm/include/llvm/AutoUpgrade.h index b638d4f59048..c774782f19ec 100644 --- a/llvm/include/llvm/AutoUpgrade.h +++ b/llvm/include/llvm/AutoUpgrade.h @@ -57,6 +57,10 @@ namespace llvm { /// with different address spaces: the instruction is replaced by a pair /// ptrtoint+inttoptr. Value *UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy); + + /// Check the debug info version number, if it is out-dated, drop the debug + /// info. Return true if module is modified. + bool UpgradeDebugInfo(Module &M); } // End llvm namespace #endif diff --git a/llvm/include/llvm/DebugInfo.h b/llvm/include/llvm/DebugInfo.h index 0ff7d8568230..7c4c1123b509 100644 --- a/llvm/include/llvm/DebugInfo.h +++ b/llvm/include/llvm/DebugInfo.h @@ -759,6 +759,9 @@ DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); /// Return true if module is modified. bool StripDebugInfo(Module &M); +/// Return Debug Info Version by checking module flags. +unsigned getDebugInfoVersionFromModule(const Module &M); + /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To /// list debug info MDNodes used by an instruction, DebugInfoFinder uses /// processDeclare, processValue and processLocation to handle DbgDeclareInst, diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 20fa0f4eab1e..3b903cdb0906 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -182,6 +182,8 @@ bool LLParser::ValidateEndOfModule() { for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove + UpgradeDebugInfo(*M); + return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 2c95c920f840..ce3b7d163e51 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3152,6 +3152,7 @@ error_code BitcodeReader::MaterializeModule(Module *M) { for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) UpgradeInstWithTBAATag(InstsWithTBAATag[I]); + UpgradeDebugInfo(*M); return error_code::success(); } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 6f79919f241d..32cfe278c73a 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/AutoUpgrade.h" +#include "llvm/DebugInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -489,3 +490,12 @@ Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { return 0; } + +/// Check the debug info version number, if it is out-dated, drop the debug +/// info. Return true if module is modified. +bool llvm::UpgradeDebugInfo(Module &M) { + if (getDebugInfoVersionFromModule(M) == DEBUG_METADATA_VERSION) + return false; + + return StripDebugInfo(M); +} diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 0c262024ff08..68015b759a73 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1477,3 +1477,11 @@ bool llvm::StripDebugInfo(Module &M) { return Changed; } + +/// Return Debug Info Version by checking module flags. +unsigned llvm::getDebugInfoVersionFromModule(const Module &M) { + Value *Val = M.getModuleFlag("Debug Info Version"); + if (!Val) + return 0; + return cast(Val)->getZExtValue(); +} diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 3dd1f7e810b0..4f240c783e90 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -318,11 +318,16 @@ getModuleFlagsMetadata(SmallVectorImpl &Flags) const { for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { MDNode *Flag = ModFlags->getOperand(i); - ConstantInt *Behavior = cast(Flag->getOperand(0)); - MDString *Key = cast(Flag->getOperand(1)); - Value *Val = Flag->getOperand(2); - Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), - Key, Val)); + if (Flag->getNumOperands() >= 3 && isa(Flag->getOperand(0)) && + isa(Flag->getOperand(1))) { + // Check the operands of the MDNode before accessing the operands. + // The verifier will actually catch these failures. + ConstantInt *Behavior = cast(Flag->getOperand(0)); + MDString *Key = cast(Flag->getOperand(1)); + Value *Val = Flag->getOperand(2); + Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), + Key, Val)); + } } } diff --git a/llvm/test/Bitcode/drop-debug-info.ll b/llvm/test/Bitcode/drop-debug-info.ll new file mode 100644 index 000000000000..da4ae0c541eb --- /dev/null +++ b/llvm/test/Bitcode/drop-debug-info.ll @@ -0,0 +1,26 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + ret i32 0, !dbg !12 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9} + +!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 (trunk 195495) (llvm/trunk 195495:195504M)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/Users/manmanren/llvm_gmail/release/../llvm/tools/clang/test/CodeGen/debug-info-version.c] [DW_LANG_C99] +!1 = metadata !{metadata !"../llvm/tools/clang/test/CodeGen/debug-info-version.c", metadata !"/Users/manmanren/llvm_gmail/release"} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main", metadata !"main", metadata !"", i32 3, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !2, i32 3} ; [ DW_TAG_subprogram ] [line 3] [def] [main] +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/Users/manmanren/llvm_gmail/release/../llvm/tools/clang/test/CodeGen/debug-info-version.c] +!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = metadata !{metadata !8} +!8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 2} +!12 = metadata !{i32 4, i32 0, metadata !4, null} + +; CHECK-NOT: !dbg +; CHECK-NOT: !llvm.dbg.cu