X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.cpp;h=4044ac80f20330b3de2a72881f5145269b097b5f;hb=3b821159da170b233a3ba8c12ce47ee6662946f0;hp=b4831d921cf911c0c52d3383b71fd2e5ce3cc176;hpb=6adbfa381528b1042c7f86b0aa59308485509560;p=oota-llvm.git diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index b4831d921cf..4044ac80f20 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -8,34 +8,378 @@ //===----------------------------------------------------------------------===// #include "llvm/Bitcode/ReaderWriter.h" -#include "BitcodeReader.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" - +#include using namespace llvm; +namespace { enum { SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; +class BitcodeReaderValueList { + std::vector ValuePtrs; + + /// ResolveConstants - As we resolve forward-referenced constants, we add + /// information about them to this vector. This allows us to resolve them in + /// bulk instead of resolving each reference at a time. See the code in + /// ResolveConstantForwardRefs for more information about this. + /// + /// The key of this vector is the placeholder constant, the value is the slot + /// number that holds the resolved value. + typedef std::vector > ResolveConstantsTy; + ResolveConstantsTy ResolveConstants; + LLVMContext &Context; +public: + BitcodeReaderValueList(LLVMContext &C) : Context(C) {} + ~BitcodeReaderValueList() { + assert(ResolveConstants.empty() && "Constants not resolved?"); + } + + // vector compatibility methods + unsigned size() const { return ValuePtrs.size(); } + void resize(unsigned N) { ValuePtrs.resize(N); } + void push_back(Value *V) { ValuePtrs.emplace_back(V); } + + void clear() { + assert(ResolveConstants.empty() && "Constants not resolved?"); + ValuePtrs.clear(); + } + + Value *operator[](unsigned i) const { + assert(i < ValuePtrs.size()); + return ValuePtrs[i]; + } + + Value *back() const { return ValuePtrs.back(); } + void pop_back() { ValuePtrs.pop_back(); } + bool empty() const { return ValuePtrs.empty(); } + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + ValuePtrs.resize(N); + } + + Constant *getConstantFwdRef(unsigned Idx, Type *Ty); + Value *getValueFwdRef(unsigned Idx, Type *Ty); + + void AssignValue(Value *V, unsigned Idx); + + /// ResolveConstantForwardRefs - Once all constants are read, this method bulk + /// resolves any forward references. + void ResolveConstantForwardRefs(); +}; + +class BitcodeReaderMDValueList { + unsigned NumFwdRefs; + bool AnyFwdRefs; + unsigned MinFwdRef; + unsigned MaxFwdRef; + std::vector MDValuePtrs; + + LLVMContext &Context; +public: + BitcodeReaderMDValueList(LLVMContext &C) + : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {} + + // vector compatibility methods + unsigned size() const { return MDValuePtrs.size(); } + void resize(unsigned N) { MDValuePtrs.resize(N); } + void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); } + void clear() { MDValuePtrs.clear(); } + Metadata *back() const { return MDValuePtrs.back(); } + void pop_back() { MDValuePtrs.pop_back(); } + bool empty() const { return MDValuePtrs.empty(); } + + Metadata *operator[](unsigned i) const { + assert(i < MDValuePtrs.size()); + return MDValuePtrs[i]; + } + + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + MDValuePtrs.resize(N); + } + + Metadata *getValueFwdRef(unsigned Idx); + void AssignValue(Metadata *MD, unsigned Idx); + void tryToResolveCycles(); +}; + +class BitcodeReader : public GVMaterializer { + LLVMContext &Context; + DiagnosticHandlerFunction DiagnosticHandler; + Module *TheModule; + std::unique_ptr Buffer; + std::unique_ptr StreamFile; + BitstreamCursor Stream; + DataStreamer *LazyStreamer; + uint64_t NextUnreadBit; + bool SeenValueSymbolTable; + + std::vector TypeList; + BitcodeReaderValueList ValueList; + BitcodeReaderMDValueList MDValueList; + std::vector ComdatList; + SmallVector InstructionList; + + std::vector > GlobalInits; + std::vector > AliasInits; + std::vector > FunctionPrefixes; + std::vector > FunctionPrologues; + + SmallVector InstsWithTBAATag; + + /// MAttributes - The set of attributes by index. Index zero in the + /// file is for null, and is thus not represented here. As such all indices + /// are off by one. + std::vector MAttributes; + + /// \brief The set of attribute groups. + std::map MAttributeGroups; + + /// FunctionBBs - While parsing a function body, this is a list of the basic + /// blocks for the function. + std::vector FunctionBBs; + + // When reading the module header, this list is populated with functions that + // have bodies later in the file. + std::vector FunctionsWithBodies; + + // When intrinsic functions are encountered which require upgrading they are + // stored here with their replacement function. + typedef std::vector > UpgradedIntrinsicMap; + UpgradedIntrinsicMap UpgradedIntrinsics; + + // Map the bitcode's custom MDKind ID to the Module's MDKind ID. + DenseMap MDKindMap; + + // Several operations happen after the module header has been read, but + // before function bodies are processed. This keeps track of whether + // we've done this yet. + bool SeenFirstFunctionBody; + + /// DeferredFunctionInfo - When function bodies are initially scanned, this + /// map contains info about where to find deferred function body in the + /// stream. + DenseMap DeferredFunctionInfo; + + /// When Metadata block is initially scanned when parsing the module, we may + /// choose to defer parsing of the metadata. This vector contains info about + /// which Metadata blocks are deferred. + std::vector DeferredMetadataInfo; + + /// These are basic blocks forward-referenced by block addresses. They are + /// inserted lazily into functions when they're loaded. The basic block ID is + /// its index into the vector. + DenseMap> BasicBlockFwdRefs; + std::deque BasicBlockFwdRefQueue; + + /// UseRelativeIDs - Indicates that we are using a new encoding for + /// instruction operands where most operands in the current + /// FUNCTION_BLOCK are encoded relative to the instruction number, + /// for a more compact encoding. Some instruction operands are not + /// relative to the instruction ID: basic block numbers, and types. + /// Once the old style function blocks have been phased out, we would + /// not need this flag. + bool UseRelativeIDs; + + /// True if all functions will be materialized, negating the need to process + /// (e.g.) blockaddress forward references. + bool WillMaterializeAllForwardRefs; + + /// Functions that have block addresses taken. This is usually empty. + SmallPtrSet BlockAddressesTaken; + + /// True if any Metadata block has been materialized. + bool IsMetadataMaterialized; + + bool StripDebugInfo = false; + +public: + std::error_code Error(BitcodeError E, const Twine &Message); + std::error_code Error(BitcodeError E); + std::error_code Error(const Twine &Message); + + explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C, + DiagnosticHandlerFunction DiagnosticHandler); + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C, + DiagnosticHandlerFunction DiagnosticHandler); + ~BitcodeReader() override { FreeState(); } + + std::error_code materializeForwardReferencedFunctions(); + + void FreeState(); + + void releaseBuffer(); + + bool isDematerializable(const GlobalValue *GV) const override; + std::error_code materialize(GlobalValue *GV) override; + std::error_code materializeModule(Module *M) override; + std::vector getIdentifiedStructTypes() const override; + void dematerialize(GlobalValue *GV) override; + + /// @brief Main interface to parsing a bitcode buffer. + /// @returns true if an error occurred. + std::error_code ParseBitcodeInto(Module *M, + bool ShouldLazyLoadMetadata = false); + + /// @brief Cheap mechanism to just extract module triple + /// @returns true if an error occurred. + ErrorOr parseTriple(); + + static uint64_t decodeSignRotatedValue(uint64_t V); + + /// Materialize any deferred Metadata block. + std::error_code materializeMetadata() override; + + void setStripDebugInfo() override; + +private: + std::vector IdentifiedStructTypes; + StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); + StructType *createIdentifiedStructType(LLVMContext &Context); + + Type *getTypeByID(unsigned ID); + Value *getFnValueByID(unsigned ID, Type *Ty) { + if (Ty && Ty->isMetadataTy()) + return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); + return ValueList.getValueFwdRef(ID, Ty); + } + Metadata *getFnMetadataByID(unsigned ID) { + return MDValueList.getValueFwdRef(ID); + } + BasicBlock *getBasicBlock(unsigned ID) const { + if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID + return FunctionBBs[ID]; + } + AttributeSet getAttributes(unsigned i) const { + if (i-1 < MAttributes.size()) + return MAttributes[i-1]; + return AttributeSet(); + } + + /// getValueTypePair - Read a value/type pair out of the specified record from + /// slot 'Slot'. Increment Slot past the number of slots used in the record. + /// Return true on failure. + bool getValueTypePair(SmallVectorImpl &Record, unsigned &Slot, + unsigned InstNum, Value *&ResVal) { + if (Slot == Record.size()) return true; + unsigned ValNo = (unsigned)Record[Slot++]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + if (ValNo < InstNum) { + // If this is not a forward reference, just return the value we already + // have. + ResVal = getFnValueByID(ValNo, nullptr); + return ResVal == nullptr; + } + if (Slot == Record.size()) + return true; + + unsigned TypeNo = (unsigned)Record[Slot++]; + ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + return ResVal == nullptr; + } + + /// popValue - Read a value out of the specified record from slot 'Slot'. + /// Increment Slot past the number of slots used by the value in the record. + /// Return true if there is an error. + bool popValue(SmallVectorImpl &Record, unsigned &Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + if (getValue(Record, Slot, InstNum, Ty, ResVal)) + return true; + // All values currently take a single record slot. + ++Slot; + return false; + } + + /// getValue -- Like popValue, but does not increment the Slot number. + bool getValue(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + ResVal = getValue(Record, Slot, InstNum, Ty); + return ResVal == nullptr; + } + + /// getValue -- Version of getValue that returns ResVal directly, + /// or 0 if there is an error. + Value *getValue(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + unsigned ValNo = (unsigned)Record[Slot]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + /// getValueSigned -- Like getValue, but decodes signed VBRs. + Value *getValueSigned(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]); + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + /// Converts alignment exponent (i.e. power of two (or zero)) to the + /// corresponding alignment to use. If alignment is too large, returns + /// a corresponding error code. + std::error_code parseAlignmentValue(uint64_t Exponent, unsigned &Alignment); + std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); + std::error_code ParseModule(bool Resume, bool ShouldLazyLoadMetadata = false); + std::error_code ParseAttributeBlock(); + std::error_code ParseAttributeGroupBlock(); + std::error_code ParseTypeTable(); + std::error_code ParseTypeTableBody(); + + std::error_code ParseValueSymbolTable(); + std::error_code ParseConstants(); + std::error_code RememberAndSkipFunctionBody(); + /// Save the positions of the Metadata blocks and skip parsing the blocks. + std::error_code rememberAndSkipMetadata(); + std::error_code ParseFunctionBody(Function *F); + std::error_code GlobalCleanup(); + std::error_code ResolveGlobalAndAliasInits(); + std::error_code ParseMetadata(); + std::error_code ParseMetadataAttachment(Function &F); + ErrorOr parseModuleTriple(); + std::error_code ParseUseLists(); + std::error_code InitStream(); + std::error_code InitStreamFromBuffer(); + std::error_code InitLazyStream(); + std::error_code FindFunctionInStream( + Function *F, + DenseMap::iterator DeferredFunctionInfoIterator); +}; +} // namespace + BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity, const Twine &Msg) @@ -55,6 +399,12 @@ static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler, return Error(DiagnosticHandler, EC, EC.message()); } +static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler, + const Twine &Message) { + return Error(DiagnosticHandler, + make_error_code(BitcodeError::CorruptedBitcode), Message); +} + std::error_code BitcodeReader::Error(BitcodeError E, const Twine &Message) { return ::Error(DiagnosticHandler, make_error_code(E), Message); } @@ -81,7 +431,7 @@ BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C, TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), - WillMaterializeAllForwardRefs(false) {} + WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {} BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C, DiagnosticHandlerFunction DiagnosticHandler) @@ -89,7 +439,7 @@ BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C, TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), - WillMaterializeAllForwardRefs(false) {} + WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {} std::error_code BitcodeReader::materializeForwardReferencedFunctions() { if (WillMaterializeAllForwardRefs) @@ -135,6 +485,7 @@ void BitcodeReader::FreeState() { std::vector().swap(FunctionBBs); std::vector().swap(FunctionsWithBodies); DeferredFunctionInfo.clear(); + DeferredMetadataInfo.clear(); MDKindMap.clear(); assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references"); @@ -260,27 +611,42 @@ static int GetDecodedCastOpcode(unsigned Val) { case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast; } } + static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) { + bool IsFP = Ty->isFPOrFPVectorTy(); + // BinOps are only valid for int/fp or vector of int/fp types + if (!IsFP && !Ty->isIntOrIntVectorTy()) + return -1; + switch (Val) { - default: return -1; + default: + return -1; case bitc::BINOP_ADD: - return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add; + return IsFP ? Instruction::FAdd : Instruction::Add; case bitc::BINOP_SUB: - return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub; + return IsFP ? Instruction::FSub : Instruction::Sub; case bitc::BINOP_MUL: - return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul; - case bitc::BINOP_UDIV: return Instruction::UDiv; + return IsFP ? Instruction::FMul : Instruction::Mul; + case bitc::BINOP_UDIV: + return IsFP ? -1 : Instruction::UDiv; case bitc::BINOP_SDIV: - return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv; - case bitc::BINOP_UREM: return Instruction::URem; + return IsFP ? Instruction::FDiv : Instruction::SDiv; + case bitc::BINOP_UREM: + return IsFP ? -1 : Instruction::URem; case bitc::BINOP_SREM: - return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem; - case bitc::BINOP_SHL: return Instruction::Shl; - case bitc::BINOP_LSHR: return Instruction::LShr; - case bitc::BINOP_ASHR: return Instruction::AShr; - case bitc::BINOP_AND: return Instruction::And; - case bitc::BINOP_OR: return Instruction::Or; - case bitc::BINOP_XOR: return Instruction::Xor; + return IsFP ? Instruction::FRem : Instruction::SRem; + case bitc::BINOP_SHL: + return IsFP ? -1 : Instruction::Shl; + case bitc::BINOP_LSHR: + return IsFP ? -1 : Instruction::LShr; + case bitc::BINOP_ASHR: + return IsFP ? -1 : Instruction::AShr; + case bitc::BINOP_AND: + return IsFP ? -1 : Instruction::And; + case bitc::BINOP_OR: + return IsFP ? -1 : Instruction::Or; + case bitc::BINOP_XOR: + return IsFP ? -1 : Instruction::Xor; } } @@ -350,7 +716,7 @@ namespace { /// @brief A class for maintaining the slot number definition /// as a placeholder for the actual definition for forward constants defs. class ConstantPlaceHolder : public ConstantExpr { - void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION; + void operator=(const ConstantPlaceHolder &) = delete; public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -417,7 +783,8 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, resize(Idx + 1); if (Value *V = ValuePtrs[Idx]) { - assert(Ty == V->getType() && "Type mismatch in constant table!"); + if (Ty != V->getType()) + report_fatal_error("Type mismatch in constant table!"); return cast(V); } @@ -428,11 +795,17 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, } Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { + // Bail out for a clearly invalid value. This would make us call resize(0) + if (Idx == UINT_MAX) + return nullptr; + if (Idx >= size()) resize(Idx + 1); if (Value *V = ValuePtrs[Idx]) { - assert((!Ty || Ty == V->getType()) && "Type mismatch in value table!"); + // If the types don't match, it's invalid. + if (Ty && Ty != V->getType()) + return nullptr; return V; } @@ -555,9 +928,17 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { if (Metadata *MD = MDValuePtrs[Idx]) return MD; - // Create and return a placeholder, which will later be RAUW'd. - AnyFwdRefs = true; + // Track forward refs to be resolved later. + if (AnyFwdRefs) { + MinFwdRef = std::min(MinFwdRef, Idx); + MaxFwdRef = std::max(MaxFwdRef, Idx); + } else { + AnyFwdRefs = true; + MinFwdRef = MaxFwdRef = Idx; + } ++NumFwdRefs; + + // Create and return a placeholder, which will later be RAUW'd. Metadata *MD = MDNode::getTemporary(Context, None).release(); MDValuePtrs[Idx].reset(MD); return MD; @@ -573,7 +954,8 @@ void BitcodeReaderMDValueList::tryToResolveCycles() { return; // Resolve any cycles. - for (auto &MD : MDValuePtrs) { + for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) { + auto &MD = MDValuePtrs[I]; auto *N = dyn_cast_or_null(MD); if (!N) continue; @@ -581,6 +963,9 @@ void BitcodeReaderMDValueList::tryToResolveCycles() { assert(!N->isTemporary() && "Unexpected forward reference"); N->resolveCycles(); } + + // Make sure we return early again until there's another forward ref. + AnyFwdRefs = false; } Type *BitcodeReader::getTypeByID(unsigned ID) { @@ -709,6 +1094,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { return Attribute::InAlloca; case bitc::ATTR_KIND_COLD: return Attribute::Cold; + case bitc::ATTR_KIND_CONVERGENT: + return Attribute::Convergent; case bitc::ATTR_KIND_INLINE_HINT: return Attribute::InlineHint; case bitc::ATTR_KIND_IN_REG: @@ -739,6 +1126,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { return Attribute::NonNull; case bitc::ATTR_KIND_DEREFERENCEABLE: return Attribute::Dereferenceable; + case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: + return Attribute::DereferenceableOrNull; case bitc::ATTR_KIND_NO_RED_ZONE: return Attribute::NoRedZone; case bitc::ATTR_KIND_NO_RETURN: @@ -782,6 +1171,16 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { } } +std::error_code BitcodeReader::parseAlignmentValue(uint64_t Exponent, + unsigned &Alignment) { + // Note: Alignment in bitcode files is incremented by 1, so that zero + // can be used for default alignment. + if (Exponent > Value::MaxAlignmentExponent + 1) + return Error("Invalid alignment value"); + Alignment = (1 << static_cast(Exponent)) >> 1; + return std::error_code(); +} + std::error_code BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { *Kind = GetAttrFromCode(Code); @@ -845,6 +1244,8 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() { B.addStackAlignmentAttr(Record[++i]); else if (Kind == Attribute::Dereferenceable) B.addDereferenceableAttr(Record[++i]); + else if (Kind == Attribute::DereferenceableOrNull) + B.addDereferenceableOrNullAttr(Record[++i]); } else { // String attribute assert((Record[i] == 3 || Record[i] == 4) && "Invalid attribute group entry"); @@ -970,7 +1371,8 @@ std::error_code BitcodeReader::ParseTypeTableBody() { if (Record.size() == 2) AddressSpace = Record[1]; ResultTy = getTypeByID(Record[0]); - if (!ResultTy) + if (!ResultTy || + !PointerType::isValidElementType(ResultTy)) return Error("Invalid type"); ResultTy = PointerType::get(ResultTy, AddressSpace); break; @@ -1001,8 +1403,11 @@ std::error_code BitcodeReader::ParseTypeTableBody() { return Error("Invalid record"); SmallVector ArgTys; for (unsigned i = 2, e = Record.size(); i != e; ++i) { - if (Type *T = getTypeByID(Record[i])) + if (Type *T = getTypeByID(Record[i])) { + if (!FunctionType::isValidArgumentType(T)) + return Error("Invalid function argument type"); ArgTys.push_back(T); + } else break; } @@ -1084,18 +1489,18 @@ std::error_code BitcodeReader::ParseTypeTableBody() { case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) return Error("Invalid record"); - if ((ResultTy = getTypeByID(Record[1]))) - ResultTy = ArrayType::get(ResultTy, Record[0]); - else + ResultTy = getTypeByID(Record[1]); + if (!ResultTy || !ArrayType::isValidElementType(ResultTy)) return Error("Invalid type"); + ResultTy = ArrayType::get(ResultTy, Record[0]); break; case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] if (Record.size() < 2) return Error("Invalid record"); - if ((ResultTy = getTypeByID(Record[1]))) - ResultTy = VectorType::get(ResultTy, Record[0]); - else + ResultTy = getTypeByID(Record[1]); + if (!ResultTy || !StructType::isValidElementType(ResultTy)) return Error("Invalid type"); + ResultTy = VectorType::get(ResultTy, Record[0]); break; } @@ -1173,7 +1578,10 @@ std::error_code BitcodeReader::ParseValueSymbolTable() { } } +static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; } + std::error_code BitcodeReader::ParseMetadata() { + IsMetadataMaterialized = true; unsigned NextMDValueNo = MDValueList.size(); if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) @@ -1181,12 +1589,17 @@ std::error_code BitcodeReader::ParseMetadata() { SmallVector Record; + auto getMD = + [&](unsigned ID) -> Metadata *{ return MDValueList.getValueFwdRef(ID); }; + auto getMDOrNull = [&](unsigned ID) -> Metadata *{ + if (ID) + return getMD(ID - 1); + return nullptr; + }; auto getMDString = [&](unsigned ID) -> MDString *{ // This requires that the ID is not really a forward reference. In // particular, the MDString must already have been resolved. - if (ID) - return cast(MDValueList.getValueFwdRef(ID - 1)); - return nullptr; + return cast_or_null(getMDOrNull(ID)); }; #define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \ @@ -1221,9 +1634,9 @@ std::error_code BitcodeReader::ParseMetadata() { Record.clear(); Code = Stream.ReadCode(); - // METADATA_NAME is always followed by METADATA_NAMED_NODE. unsigned NextBitCode = Stream.readRecord(Code, Record); - assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode; + if (NextBitCode != bitc::METADATA_NAMED_NODE) + return Error("METADATA_NAME not followed by METADATA_NAMED_NODE"); // Read named metadata elements. unsigned Size = Record.size(); @@ -1319,14 +1732,15 @@ std::error_code BitcodeReader::ParseMetadata() { if (Record.size() != 5) return Error("Invalid record"); - auto get = Record[0] ? MDLocation::getDistinct : MDLocation::get; unsigned Line = Record[1]; unsigned Column = Record[2]; MDNode *Scope = cast(MDValueList.getValueFwdRef(Record[3])); Metadata *InlinedAt = Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr; - MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt), - NextMDValueNo++); + MDValueList.AssignValue( + GET_OR_DISTINCT(DILocation, Record[0], + (Context, Line, Column, Scope, InlinedAt)), + NextMDValueNo++); break; } case bitc::METADATA_GENERIC_DEBUG: { @@ -1344,11 +1758,244 @@ std::error_code BitcodeReader::ParseMetadata() { for (unsigned I = 4, E = Record.size(); I != E; ++I) DwarfOps.push_back(Record[I] ? MDValueList.getValueFwdRef(Record[I] - 1) : nullptr); - MDValueList.AssignValue(GET_OR_DISTINCT(GenericDebugNode, Record[0], + MDValueList.AssignValue(GET_OR_DISTINCT(GenericDINode, Record[0], (Context, Tag, Header, DwarfOps)), NextMDValueNo++); break; } + case bitc::METADATA_SUBRANGE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DISubrange, Record[0], + (Context, Record[1], unrotateSign(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_ENUMERATOR: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue(GET_OR_DISTINCT(DIEnumerator, Record[0], + (Context, unrotateSign(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_BASIC_TYPE: { + if (Record.size() != 6) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIBasicType, Record[0], + (Context, Record[1], getMDString(Record[2]), + Record[3], Record[4], Record[5])), + NextMDValueNo++); + break; + } + case bitc::METADATA_DERIVED_TYPE: { + if (Record.size() != 12) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIDerivedType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPOSITE_TYPE: { + if (Record.size() != 16) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DICompositeType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]), Record[12], + getMDOrNull(Record[13]), getMDOrNull(Record[14]), + getMDString(Record[15]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBROUTINE_TYPE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DISubroutineType, Record[0], + (Context, Record[1], getMDOrNull(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_FILE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIFile, Record[0], (Context, getMDString(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPILE_UNIT: { + if (Record.size() < 14 || Record.size() > 15) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DICompileUnit, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), Record[4], + getMDString(Record[5]), Record[6], + getMDString(Record[7]), Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + getMDOrNull(Record[11]), getMDOrNull(Record[12]), + getMDOrNull(Record[13]), + Record.size() == 14 ? 0 : Record[14])), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBPROGRAM: { + if (Record.size() != 19) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT( + DISubprogram, Record[0], + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], Record[9], + getMDOrNull(Record[10]), Record[11], Record[12], Record[13], + Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]), + getMDOrNull(Record[17]), getMDOrNull(Record[18]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DILexicalBlock, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3], Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK_FILE: { + if (Record.size() != 4) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DILexicalBlockFile, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3])), + NextMDValueNo++); + break; + } + case bitc::METADATA_NAMESPACE: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DINamespace, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), getMDString(Record[3]), + Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_TEMPLATE_TYPE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue(GET_OR_DISTINCT(DITemplateTypeParameter, + Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_TEMPLATE_VALUE: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DITemplateValueParameter, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), getMDOrNull(Record[4]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_GLOBAL_VAR: { + if (Record.size() != 11) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIGlobalVariable, Record[0], + (Context, getMDOrNull(Record[1]), + getMDString(Record[2]), getMDString(Record[3]), + getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LOCAL_VAR: { + // 10th field is for the obseleted 'inlinedAt:' field. + if (Record.size() != 9 && Record.size() != 10) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DILocalVariable, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), + Record[5], getMDOrNull(Record[6]), Record[7], + Record[8])), + NextMDValueNo++); + break; + } + case bitc::METADATA_EXPRESSION: { + if (Record.size() < 1) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIExpression, Record[0], + (Context, makeArrayRef(Record).slice(1))), + NextMDValueNo++); + break; + } + case bitc::METADATA_OBJC_PROPERTY: { + if (Record.size() != 8) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIObjCProperty, Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]), Record[3], + getMDString(Record[4]), getMDString(Record[5]), + Record[6], getMDOrNull(Record[7]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_IMPORTED_ENTITY: { + if (Record.size() != 6) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(DIImportedEntity, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDString(Record[5]))), + NextMDValueNo++); + break; + } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); llvm::UpgradeMDStringConstant(String); @@ -1692,19 +2339,29 @@ std::error_code BitcodeReader::ParseConstants() { } case bitc::CST_CODE_CE_INBOUNDS_GEP: case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands] - if (Record.size() & 1) - return Error("Invalid record"); + unsigned OpNum = 0; + Type *PointeeType = nullptr; + if (Record.size() % 2) + PointeeType = getTypeByID(Record[OpNum++]); SmallVector Elts; - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Type *ElTy = getTypeByID(Record[i]); + while (OpNum != Record.size()) { + Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return Error("Invalid record"); - Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); + Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } + + if (PointeeType && + PointeeType != + cast(Elts[0]->getType()->getScalarType()) + ->getElementType()) + return Error("Explicit gep operator type does not match pointee type " + "of pointer operand"); + ArrayRef Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(Elts[0], Indices, + V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, BitCode == - bitc::CST_CODE_CE_INBOUNDS_GEP); + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] @@ -1974,6 +2631,32 @@ std::error_code BitcodeReader::ParseUseLists() { } } +/// When we see the block for metadata, remember where it is and then skip it. +/// This lets us lazily deserialize the metadata. +std::error_code BitcodeReader::rememberAndSkipMetadata() { + // Save the current stream state. + uint64_t CurBit = Stream.GetCurrentBitNo(); + DeferredMetadataInfo.push_back(CurBit); + + // Skip over the block for now. + if (Stream.SkipBlock()) + return Error("Invalid record"); + return std::error_code(); +} + +std::error_code BitcodeReader::materializeMetadata() { + for (uint64_t BitPos : DeferredMetadataInfo) { + // Move the bit stream to the saved position. + Stream.JumpToBit(BitPos); + if (std::error_code EC = ParseMetadata()) + return EC; + } + DeferredMetadataInfo.clear(); + return std::error_code(); +} + +void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; } + /// RememberAndSkipFunctionBody - When we see the block for a function body, /// remember where it is and then skip it. This lets us lazily deserialize the /// functions. @@ -2024,7 +2707,8 @@ std::error_code BitcodeReader::GlobalCleanup() { return std::error_code(); } -std::error_code BitcodeReader::ParseModule(bool Resume) { +std::error_code BitcodeReader::ParseModule(bool Resume, + bool ShouldLazyLoadMetadata) { if (Resume) Stream.JumpToBit(NextUnreadBit); else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) @@ -2078,6 +2762,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { return EC; break; case bitc::METADATA_BLOCK_ID: + if (ShouldLazyLoadMetadata && !IsMetadataMaterialized) { + if (std::error_code EC = rememberAndSkipMetadata()) + return EC; + break; + } + assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata"); if (std::error_code EC = ParseMetadata()) return EC; break; @@ -2196,22 +2886,31 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { } // GLOBALVAR: [pointer type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, dllstorageclass] + // unnamed_addr, externally_initialized, dllstorageclass, + // comdat] case bitc::MODULE_CODE_GLOBALVAR: { if (Record.size() < 6) return Error("Invalid record"); Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid record"); - if (!Ty->isPointerTy()) - return Error("Invalid type for value"); - unsigned AddressSpace = cast(Ty)->getAddressSpace(); - Ty = cast(Ty)->getElementType(); + bool isConstant = Record[1] & 1; + bool explicitType = Record[1] & 2; + unsigned AddressSpace; + if (explicitType) { + AddressSpace = Record[1] >> 2; + } else { + if (!Ty->isPointerTy()) + return Error("Invalid type for value"); + AddressSpace = cast(Ty)->getAddressSpace(); + Ty = cast(Ty)->getElementType(); + } - bool isConstant = Record[1]; uint64_t RawLinkage = Record[3]; GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - unsigned Alignment = (1 << Record[4]) >> 1; + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[4], Alignment)) + return EC; std::string Section; if (Record[5]) { if (Record[5]-1 >= SectionTable.size()) @@ -2258,7 +2957,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { if (Record.size() > 11) { if (unsigned ComdatID = Record[11]) { - assert(ComdatID <= ComdatList.size()); + if (ComdatID > ComdatList.size()) + return Error("Invalid global variable comdat ID"); NewGV->setComdat(ComdatList[ComdatID - 1]); } } else if (hasImplicitComdat(RawLinkage)) { @@ -2275,10 +2975,9 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid record"); - if (!Ty->isPointerTy()) - return Error("Invalid type for value"); - FunctionType *FTy = - dyn_cast(cast(Ty)->getElementType()); + if (auto *PTy = dyn_cast(Ty)) + Ty = PTy->getElementType(); + auto *FTy = dyn_cast(Ty); if (!FTy) return Error("Invalid type for value"); @@ -2291,7 +2990,10 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { Func->setLinkage(getDecodedLinkage(RawLinkage)); Func->setAttributes(getAttributes(Record[4])); - Func->setAlignment((1 << Record[5]) >> 1); + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[5], Alignment)) + return EC; + Func->setAlignment(Alignment); if (Record[6]) { if (Record[6]-1 >= SectionTable.size()) return Error("Invalid ID"); @@ -2302,7 +3004,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { // FIXME: Change to an error if non-default in 4.0. Func->setVisibility(GetDecodedVisibility(Record[7])); if (Record.size() > 8 && Record[8]) { - if (Record[8]-1 > GCTable.size()) + if (Record[8]-1 >= GCTable.size()) return Error("Invalid ID"); Func->setGC(GCTable[Record[8]-1].c_str()); } @@ -2320,7 +3022,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { if (Record.size() > 12) { if (unsigned ComdatID = Record[12]) { - assert(ComdatID <= ComdatList.size()); + if (ComdatID > ComdatList.size()) + return Error("Invalid function comdat ID"); Func->setComdat(ComdatList[ComdatID - 1]); } } else if (hasImplicitComdat(RawLinkage)) { @@ -2355,8 +3058,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { return Error("Invalid type for value"); auto *NewGA = - GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), - getDecodedLinkage(Record[2]), "", TheModule); + GlobalAlias::create(PTy, getDecodedLinkage(Record[2]), "", TheModule); // Old bitcode files didn't have visibility field. // Local linkage must have default visibility. if (Record.size() > 3 && !NewGA->hasLocalLinkage()) @@ -2386,7 +3088,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { } } -std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { +std::error_code BitcodeReader::ParseBitcodeInto(Module *M, + bool ShouldLazyLoadMetadata) { TheModule = nullptr; if (std::error_code EC = InitStream()) @@ -2404,8 +3107,12 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (1) { - if (Stream.AtEndOfStream()) - return std::error_code(); + if (Stream.AtEndOfStream()) { + if (TheModule) + return std::error_code(); + // We didn't really read a proper Module. + return Error("Malformed IR file"); + } BitstreamEntry Entry = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); @@ -2427,7 +3134,7 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { if (TheModule) return Error("Invalid multiple blocks"); TheModule = M; - if (std::error_code EC = ParseModule(false)) + if (std::error_code EC = ParseModule(false, ShouldLazyLoadMetadata)) return EC; if (LazyStreamer) return std::error_code(); @@ -2533,7 +3240,7 @@ ErrorOr BitcodeReader::parseTriple() { } /// ParseMetadataAttachment - Parse metadata attachments. -std::error_code BitcodeReader::ParseMetadataAttachment() { +std::error_code BitcodeReader::ParseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) return Error("Invalid record"); @@ -2559,8 +3266,21 @@ std::error_code BitcodeReader::ParseMetadataAttachment() { break; case bitc::METADATA_ATTACHMENT: { unsigned RecordLength = Record.size(); - if (Record.empty() || (RecordLength - 1) % 2 == 1) + if (Record.empty()) return Error("Invalid record"); + if (RecordLength % 2 == 0) { + // A function attachment. + for (unsigned I = 0; I != RecordLength; I += 2) { + auto K = MDKindMap.find(Record[I]); + if (K == MDKindMap.end()) + return Error("Invalid ID"); + Metadata *MD = MDValueList.getValueFwdRef(Record[I + 1]); + F.setMetadata(K->second, cast(MD)); + } + continue; + } + + // An instruction attachment. Instruction *Inst = InstructionList[Record[0]]; for (unsigned i = 1; i != RecordLength; i = i+2) { unsigned Kind = Record[i]; @@ -2583,6 +3303,20 @@ std::error_code BitcodeReader::ParseMetadataAttachment() { } } +static std::error_code TypeCheckLoadStoreInst(DiagnosticHandlerFunction DH, + Type *ValType, Type *PtrType) { + if (!isa(PtrType)) + return Error(DH, "Load/Store operand is not a pointer type"); + Type *ElemType = cast(PtrType)->getElementType(); + + if (ValType && ValType != ElemType) + return Error(DH, "Explicit load/store type does not match pointee type of " + "pointer operand"); + if (!PointerType::isLoadableOrStorableType(ElemType)) + return Error(DH, "Cannot load/store from pointer"); + return std::error_code(); +} + /// ParseFunctionBody - Lazily parse the specified function body block. std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) @@ -2637,7 +3371,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return EC; break; case bitc::METADATA_ATTACHMENT_ID: - if (std::error_code EC = ParseMetadataAttachment()) + if (std::error_code EC = ParseMetadataAttachment(*F)) return EC; break; case bitc::METADATA_BLOCK_ID: @@ -2796,13 +3530,35 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_INBOUNDS_GEP: - case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands] + case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands] unsigned OpNum = 0; + + Type *Ty; + bool InBounds; + + if (BitCode == bitc::FUNC_CODE_INST_GEP) { + InBounds = Record[OpNum++]; + Ty = getTypeByID(Record[OpNum++]); + } else { + InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + Ty = nullptr; + } + Value *BasePtr; if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return Error("Invalid record"); + if (!Ty) + Ty = cast(BasePtr->getType()->getScalarType()) + ->getElementType(); + else if (Ty != + cast(BasePtr->getType()->getScalarType()) + ->getElementType()) + return Error( + "Explicit gep type does not match pointee type of pointer operand"); + SmallVector GEPIdx; while (OpNum != Record.size()) { Value *Op; @@ -2811,9 +3567,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { GEPIdx.push_back(Op); } - I = GetElementPtrInst::Create(BasePtr, GEPIdx); + I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + InstructionList.push_back(I); - if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) + if (InBounds) cast(I)->setIsInBounds(true); break; } @@ -2825,13 +3582,31 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) return Error("Invalid record"); + unsigned RecSize = Record.size(); + if (OpNum == RecSize) + return Error("EXTRACTVAL: Invalid instruction with 0 indices"); + SmallVector EXTRACTVALIdx; - for (unsigned RecSize = Record.size(); - OpNum != RecSize; ++OpNum) { + Type *CurTy = Agg->getType(); + for (; OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("EXTRACTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); + + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -2849,15 +3624,36 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Val)) return Error("Invalid record"); + unsigned RecSize = Record.size(); + if (OpNum == RecSize) + return Error("INSERTVAL: Invalid instruction with 0 indices"); + SmallVector INSERTVALIdx; - for (unsigned RecSize = Record.size(); - OpNum != RecSize; ++OpNum) { + Type *CurTy = Agg->getType(); + for (; OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("INSERTVAL: Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("INSERTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("INSERTVAL: Invalid array index"); + INSERTVALIdx.push_back((unsigned)Index); + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } + if (CurTy != Val->getType()) + return Error("Inserted value type doesn't match aggregate type"); + I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); InstructionList.push_back(I); break; @@ -2911,6 +3707,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || getValueTypePair(Record, OpNum, NextValueNo, Idx)) return Error("Invalid record"); + if (!Vec->getType()->isVectorTy()) + return Error("Invalid type for value"); I = ExtractElementInst::Create(Vec, Idx); InstructionList.push_back(I); break; @@ -2919,8 +3717,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] unsigned OpNum = 0; Value *Vec, *Elt, *Idx; - if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || - popValue(Record, OpNum, NextValueNo, + if (getValueTypePair(Record, OpNum, NextValueNo, Vec)) + return Error("Invalid record"); + if (!Vec->getType()->isVectorTy()) + return Error("Invalid type for value"); + if (popValue(Record, OpNum, NextValueNo, cast(Vec->getType())->getElementType(), Elt) || getValueTypePair(Record, OpNum, NextValueNo, Idx)) return Error("Invalid record"); @@ -2938,6 +3739,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) return Error("Invalid record"); + if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy()) + return Error("Invalid type for value"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); InstructionList.push_back(I); break; @@ -3121,24 +3924,33 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...] if (Record.size() < 4) return Error("Invalid record"); - AttributeSet PAL = getAttributes(Record[0]); - unsigned CCInfo = Record[1]; - BasicBlock *NormalBB = getBasicBlock(Record[2]); - BasicBlock *UnwindBB = getBasicBlock(Record[3]); + unsigned OpNum = 0; + AttributeSet PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]); + BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]); + + FunctionType *FTy = nullptr; + if (CCInfo >> 13 & 1 && + !(FTy = dyn_cast(getTypeByID(Record[OpNum++])))) + return Error("Explicit invoke type is not a function type"); - unsigned OpNum = 4; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid record"); PointerType *CalleeTy = dyn_cast(Callee->getType()); - FunctionType *FTy = !CalleeTy ? nullptr : - dyn_cast(CalleeTy->getElementType()); - - // Check that the right number of fixed parameters are here. - if (!FTy || !NormalBB || !UnwindBB || - Record.size() < OpNum+FTy->getNumParams()) - return Error("Invalid record"); + if (!CalleeTy) + return Error("Callee is not a pointer"); + if (!FTy) { + FTy = dyn_cast(CalleeTy->getElementType()); + if (!FTy) + return Error("Callee is not of pointer to function type"); + } else if (CalleeTy->getElementType() != FTy) + return Error("Explicit invoke type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return Error("Insufficient operands to call"); SmallVector Ops; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { @@ -3163,8 +3975,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops); InstructionList.push_back(I); - cast(I)->setCallingConv( - static_cast(CCInfo)); + cast(I) + ->setCallingConv(static_cast(~(1U << 13) & CCInfo)); cast(I)->setAttributes(PAL); break; } @@ -3252,16 +4064,28 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] if (Record.size() != 4) return Error("Invalid record"); - PointerType *Ty = - dyn_cast_or_null(getTypeByID(Record[0])); + uint64_t AlignRecord = Record[3]; + const uint64_t InAllocaMask = uint64_t(1) << 5; + const uint64_t ExplicitTypeMask = uint64_t(1) << 6; + const uint64_t FlagMask = InAllocaMask | ExplicitTypeMask; + bool InAlloca = AlignRecord & InAllocaMask; + Type *Ty = getTypeByID(Record[0]); + if ((AlignRecord & ExplicitTypeMask) == 0) { + auto *PTy = dyn_cast_or_null(Ty); + if (!PTy) + return Error("Old-style alloca with a non-pointer type"); + Ty = PTy->getElementType(); + } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); - unsigned AlignRecord = Record[3]; - bool InAlloca = AlignRecord & (1 << 5); - unsigned Align = AlignRecord & ((1 << 5) - 1); + unsigned Align; + if (std::error_code EC = + parseAlignmentValue(AlignRecord & ~FlagMask, Align)) { + return EC; + } if (!Ty || !Size) return Error("Invalid record"); - AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); + AllocaInst *AI = new AllocaInst(Ty, Size, Align); AI->setUsedWithInAlloca(InAlloca); I = AI; InstructionList.push_back(I); @@ -3271,10 +4095,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+2 != Record.size()) + (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return Error("Invalid record"); - I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1); + Type *Ty = nullptr; + if (OpNum + 3 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + if (std::error_code EC = + TypeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType())) + return EC; + if (!Ty) + Ty = cast(Op->getType())->getElementType(); + + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align); + InstructionList.push_back(I); break; } @@ -3283,9 +4120,18 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+4 != Record.size()) + (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return Error("Invalid record"); + Type *Ty = nullptr; + if (OpNum + 5 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + if (std::error_code EC = + TypeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType())) + return EC; + if (!Ty) + Ty = cast(Op->getType())->getElementType(); + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Release || Ordering == AcquireRelease) @@ -3294,34 +4140,54 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); - I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1, - Ordering, SynchScope); + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); + InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_STORE: { // STORE2:[ptrty, ptr, val, align, vol] + case bitc::FUNC_CODE_INST_STORE: + case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), Val) || - OpNum+2 != Record.size()) - return Error("Invalid record"); - - I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1); + (BitCode == bitc::FUNC_CODE_INST_STORE + ? getValueTypePair(Record, OpNum, NextValueNo, Val) + : popValue(Record, OpNum, NextValueNo, + cast(Ptr->getType())->getElementType(), + Val)) || + OpNum + 2 != Record.size()) + return Error("Invalid record"); + + if (std::error_code EC = TypeCheckLoadStoreInst( + DiagnosticHandler, Val->getType(), Ptr->getType())) + return EC; + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align); InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_STOREATOMIC: { + case bitc::FUNC_CODE_INST_STOREATOMIC: + case bitc::FUNC_CODE_INST_STOREATOMIC_OLD: { // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope] unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), Val) || - OpNum+4 != Record.size()) + (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC + ? getValueTypePair(Record, OpNum, NextValueNo, Val) + : popValue(Record, OpNum, NextValueNo, + cast(Ptr->getType())->getElementType(), + Val)) || + OpNum + 4 != Record.size()) return Error("Invalid record"); + if (std::error_code EC = TypeCheckLoadStoreInst( + DiagnosticHandler, Val->getType(), Ptr->getType())) + return EC; AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Acquire || Ordering == AcquireRelease) @@ -3330,28 +4196,36 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Ordering != NotAtomic && Record[OpNum] == 0) return Error("Invalid record"); - I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1, - Ordering, SynchScope); + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SynchScope); InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_CMPXCHG_OLD: case bitc::FUNC_CODE_INST_CMPXCHG: { // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, synchscope, // failureordering?, isweak?] unsigned OpNum = 0; Value *Ptr, *Cmp, *New; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), Cmp) || - popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), New) || - (Record.size() < OpNum + 3 || Record.size() > OpNum + 5)) + (BitCode == bitc::FUNC_CODE_INST_CMPXCHG + ? getValueTypePair(Record, OpNum, NextValueNo, Cmp) + : popValue(Record, OpNum, NextValueNo, + cast(Ptr->getType())->getElementType(), + Cmp)) || + popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || + Record.size() < OpNum + 3 || Record.size() > OpNum + 5) return Error("Invalid record"); AtomicOrdering SuccessOrdering = GetDecodedOrdering(Record[OpNum+1]); if (SuccessOrdering == NotAtomic || SuccessOrdering == Unordered) return Error("Invalid record"); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]); + if (std::error_code EC = TypeCheckLoadStoreInst( + DiagnosticHandler, Cmp->getType(), Ptr->getType())) + return EC; AtomicOrdering FailureOrdering; if (Record.size() < 7) FailureOrdering = @@ -3415,19 +4289,31 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid record"); - AttributeSet PAL = getAttributes(Record[0]); - unsigned CCInfo = Record[1]; + unsigned OpNum = 0; + AttributeSet PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + + FunctionType *FTy = nullptr; + if (CCInfo >> 15 & 1 && + !(FTy = dyn_cast(getTypeByID(Record[OpNum++])))) + return Error("Explicit call type is not a function type"); - unsigned OpNum = 2; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid record"); PointerType *OpTy = dyn_cast(Callee->getType()); - FunctionType *FTy = nullptr; - if (OpTy) FTy = dyn_cast(OpTy->getElementType()); - if (!FTy || Record.size() < FTy->getNumParams()+OpNum) - return Error("Invalid record"); + if (!OpTy) + return Error("Callee is not a pointer type"); + if (!FTy) { + FTy = dyn_cast(OpTy->getElementType()); + if (!FTy) + return Error("Callee is not of pointer to function type"); + } else if (OpTy->getElementType() != FTy) + return Error("Explicit call type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return Error("Insufficient operands to call"); SmallVector Args; // Read the fixed params. @@ -3454,7 +4340,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { } } - I = CallInst::Create(Callee, Args); + I = CallInst::Create(FTy, Callee, Args); InstructionList.push_back(I); cast(I)->setCallingConv( static_cast((~(1U << 14) & CCInfo) >> 1)); @@ -3548,6 +4434,9 @@ std::error_code BitcodeReader::FindFunctionInStream( void BitcodeReader::releaseBuffer() { Buffer.release(); } std::error_code BitcodeReader::materialize(GlobalValue *GV) { + if (std::error_code EC = materializeMetadata()) + return EC; + Function *F = dyn_cast(GV); // If it's not a function or is already material, ignore the request. if (!F || !F->isMaterializable()) @@ -3568,6 +4457,9 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) { return EC; F->setIsMaterializable(false); + if (StripDebugInfo) + stripDebugInfo(*F); + // Upgrade any old intrinsic calls in the function. for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) { @@ -3598,7 +4490,7 @@ bool BitcodeReader::isDematerializable(const GlobalValue *GV) const { return DeferredFunctionInfo.count(const_cast(F)); } -void BitcodeReader::Dematerialize(GlobalValue *GV) { +void BitcodeReader::dematerialize(GlobalValue *GV) { Function *F = dyn_cast(GV); // If this function isn't dematerializable, this is a noop. if (!F || !isDematerializable(F)) @@ -3611,10 +4503,13 @@ void BitcodeReader::Dematerialize(GlobalValue *GV) { F->setIsMaterializable(true); } -std::error_code BitcodeReader::MaterializeModule(Module *M) { +std::error_code BitcodeReader::materializeModule(Module *M) { assert(M == TheModule && "Can only Materialize the Module this BitcodeReader is attached to."); + if (std::error_code EC = materializeMetadata()) + return EC; + // Promise to materialize all forward references. WillMaterializeAllForwardRefs = true; @@ -3755,7 +4650,8 @@ const std::error_category &llvm::BitcodeErrorCategory() { static ErrorOr getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, LLVMContext &Context, bool WillMaterializeAll, - DiagnosticHandlerFunction DiagnosticHandler) { + DiagnosticHandlerFunction DiagnosticHandler, + bool ShouldLazyLoadMetadata = false) { Module *M = new Module(Buffer->getBufferIdentifier(), Context); BitcodeReader *R = new BitcodeReader(Buffer.get(), Context, DiagnosticHandler); @@ -3767,7 +4663,8 @@ getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, return EC; }; - if (std::error_code EC = R->ParseBitcodeInto(M)) + // Delay parsing Metadata if ShouldLazyLoadMetadata is true. + if (std::error_code EC = R->ParseBitcodeInto(M, ShouldLazyLoadMetadata)) return cleanupOnError(EC); if (!WillMaterializeAll) @@ -3782,9 +4679,10 @@ getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, ErrorOr llvm::getLazyBitcodeModule(std::unique_ptr &&Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler) { + DiagnosticHandlerFunction DiagnosticHandler, + bool ShouldLazyLoadMetadata) { return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false, - DiagnosticHandler); + DiagnosticHandler, ShouldLazyLoadMetadata); } ErrorOr>