summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp1280
1 files changed, 1124 insertions, 156 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 3d9546f..056d87b 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -8,32 +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 <deque>
using namespace llvm;
+namespace {
enum {
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
};
+class BitcodeReaderValueList {
+ std::vector<WeakVH> 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<std::pair<Constant*, unsigned> > 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<TrackingMDRef> 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<MemoryBuffer> Buffer;
+ std::unique_ptr<BitstreamReader> StreamFile;
+ BitstreamCursor Stream;
+ DataStreamer *LazyStreamer;
+ uint64_t NextUnreadBit;
+ bool SeenValueSymbolTable;
+
+ std::vector<Type*> TypeList;
+ BitcodeReaderValueList ValueList;
+ BitcodeReaderMDValueList MDValueList;
+ std::vector<Comdat *> ComdatList;
+ SmallVector<Instruction *, 64> InstructionList;
+
+ std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+ std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
+
+ SmallVector<Instruction*, 64> 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<AttributeSet> MAttributes;
+
+ /// \brief The set of attribute groups.
+ std::map<unsigned, AttributeSet> MAttributeGroups;
+
+ /// FunctionBBs - While parsing a function body, this is a list of the basic
+ /// blocks for the function.
+ std::vector<BasicBlock*> FunctionBBs;
+
+ // When reading the module header, this list is populated with functions that
+ // have bodies later in the file.
+ std::vector<Function*> FunctionsWithBodies;
+
+ // When intrinsic functions are encountered which require upgrading they are
+ // stored here with their replacement function.
+ typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
+ UpgradedIntrinsicMap UpgradedIntrinsics;
+
+ // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
+ DenseMap<unsigned, unsigned> 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<Function*, uint64_t> 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<uint64_t> 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<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs;
+ std::deque<Function *> 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<const Function *, 4> 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<StructType *> 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<std::string> parseTriple();
+
+ static uint64_t decodeSignRotatedValue(uint64_t V);
+
+ /// Materialize any deferred Metadata block.
+ std::error_code materializeMetadata() override;
+
+ void setStripDebugInfo() override;
+
+private:
+ std::vector<StructType *> 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<uint64_t> &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<uint64_t> &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<uint64_t> &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<uint64_t> &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<uint64_t> &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<std::string> parseModuleTriple();
+ std::error_code ParseUseLists();
+ std::error_code InitStream();
+ std::error_code InitStreamFromBuffer();
+ std::error_code InitLazyStream();
+ std::error_code FindFunctionInStream(
+ Function *F,
+ DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator);
+};
+} // namespace
+
BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC,
DiagnosticSeverity Severity,
const Twine &Msg)
@@ -53,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);
}
@@ -79,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)
@@ -87,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)
@@ -133,6 +485,7 @@ void BitcodeReader::FreeState() {
std::vector<BasicBlock*>().swap(FunctionBBs);
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
+ DeferredMetadataInfo.clear();
MDKindMap.clear();
assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references");
@@ -156,19 +509,27 @@ static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
return false;
}
+static bool hasImplicitComdat(size_t Val) {
+ switch (Val) {
+ default:
+ return false;
+ case 1: // Old WeakAnyLinkage
+ case 4: // Old LinkOnceAnyLinkage
+ case 10: // Old WeakODRLinkage
+ case 11: // Old LinkOnceODRLinkage
+ return true;
+ }
+}
+
static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
switch (Val) {
default: // Map unknown/new linkages to external
case 0:
return GlobalValue::ExternalLinkage;
- case 1:
- return GlobalValue::WeakAnyLinkage;
case 2:
return GlobalValue::AppendingLinkage;
case 3:
return GlobalValue::InternalLinkage;
- case 4:
- return GlobalValue::LinkOnceAnyLinkage;
case 5:
return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
case 6:
@@ -179,10 +540,6 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
return GlobalValue::CommonLinkage;
case 9:
return GlobalValue::PrivateLinkage;
- case 10:
- return GlobalValue::WeakODRLinkage;
- case 11:
- return GlobalValue::LinkOnceODRLinkage;
case 12:
return GlobalValue::AvailableExternallyLinkage;
case 13:
@@ -191,6 +548,18 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateWeakLinkage
case 15:
return GlobalValue::ExternalLinkage; // Obsolete LinkOnceODRAutoHideLinkage
+ case 1: // Old value with implicit comdat.
+ case 16:
+ return GlobalValue::WeakAnyLinkage;
+ case 10: // Old value with implicit comdat.
+ case 17:
+ return GlobalValue::WeakODRLinkage;
+ case 4: // Old value with implicit comdat.
+ case 18:
+ return GlobalValue::LinkOnceAnyLinkage;
+ case 11: // Old value with implicit comdat.
+ case 19:
+ return GlobalValue::LinkOnceODRLinkage;
}
}
@@ -242,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;
}
}
@@ -332,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) {
@@ -399,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<Constant>(V);
}
@@ -410,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;
}
@@ -525,9 +916,8 @@ void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
}
// If there was a forward reference to this value, replace it.
- MDNodeFwdDecl *PrevMD = cast<MDNodeFwdDecl>(OldMD.get());
+ TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
PrevMD->replaceAllUsesWith(MD);
- MDNode::deleteTemporary(PrevMD);
--NumFwdRefs;
}
@@ -549,7 +939,7 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
++NumFwdRefs;
// Create and return a placeholder, which will later be RAUW'd.
- Metadata *MD = MDNode::getTemporary(Context, None);
+ Metadata *MD = MDNode::getTemporary(Context, None).release();
MDValuePtrs[Idx].reset(MD);
return MD;
}
@@ -566,9 +956,12 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
// Resolve any cycles.
for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
auto &MD = MDValuePtrs[I];
- assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
- if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))
- N->resolveCycles();
+ auto *N = dyn_cast_or_null<MDNode>(MD);
+ if (!N)
+ continue;
+
+ assert(!N->isTemporary() && "Unexpected forward reference");
+ N->resolveCycles();
}
// Make sure we return early again until there's another forward ref.
@@ -701,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:
@@ -731,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:
@@ -774,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<unsigned>(Exponent)) >> 1;
+ return std::error_code();
+}
+
std::error_code BitcodeReader::ParseAttrKind(uint64_t Code,
Attribute::AttrKind *Kind) {
*Kind = GetAttrFromCode(Code);
@@ -837,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");
@@ -943,12 +1352,17 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_X86_MMX: // X86_MMX
ResultTy = Type::getX86_MMXTy(Context);
break;
- case bitc::TYPE_CODE_INTEGER: // INTEGER: [width]
+ case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width]
if (Record.size() < 1)
return Error("Invalid record");
- ResultTy = IntegerType::get(Context, Record[0]);
+ uint64_t NumBits = Record[0];
+ if (NumBits < IntegerType::MIN_INT_BITS ||
+ NumBits > IntegerType::MAX_INT_BITS)
+ return Error("Bitwidth for integer type out of range");
+ ResultTy = IntegerType::get(Context, NumBits);
break;
+ }
case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
// [pointee type, address space]
if (Record.size() < 1)
@@ -957,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;
@@ -988,8 +1403,11 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
return Error("Invalid record");
SmallVector<Type*, 8> 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;
}
@@ -1071,25 +1489,29 @@ 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
+ if (Record[0] == 0)
+ return Error("Invalid vector length");
+ ResultTy = getTypeByID(Record[1]);
+ if (!ResultTy || !StructType::isValidElementType(ResultTy))
return Error("Invalid type");
+ ResultTy = VectorType::get(ResultTy, Record[0]);
break;
}
if (NumRecords >= TypeList.size())
return Error("Invalid TYPE table");
+ if (TypeList[NumRecords])
+ return Error(
+ "Invalid TYPE table: Only named structs can be forward referenced");
assert(ResultTy && "Didn't read a type?");
- assert(!TypeList[NumRecords] && "Already read type?");
TypeList[NumRecords++] = ResultTy;
}
}
@@ -1100,6 +1522,8 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
SmallVector<uint64_t, 64> Record;
+ Triple TT(TheModule->getTargetTriple());
+
// Read all the records for this value table.
SmallString<128> ValueName;
while (1) {
@@ -1130,6 +1554,14 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
Value *V = ValueList[ValueID];
V->setName(StringRef(ValueName.data(), ValueName.size()));
+ if (auto *GO = dyn_cast<GlobalObject>(V)) {
+ if (GO->getComdat() == reinterpret_cast<Comdat *>(1)) {
+ if (TT.isOSBinFormatMachO())
+ GO->setComdat(nullptr);
+ else
+ GO->setComdat(TheModule->getOrInsertComdat(V->getName()));
+ }
+ }
ValueName.clear();
break;
}
@@ -1148,7 +1580,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))
@@ -1156,6 +1591,22 @@ std::error_code BitcodeReader::ParseMetadata() {
SmallVector<uint64_t, 64> 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.
+ return cast_or_null<MDString>(getMDOrNull(ID));
+ };
+
+#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \
+ (DISTINCT ? CLASS::getDistinct ARGS : CLASS::get ARGS)
+
// Read all the records.
while (1) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -1185,9 +1636,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();
@@ -1283,16 +1734,270 @@ 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<MDNode>(MDValueList.getValueFwdRef(Record[3]));
Metadata *InlinedAt =
Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr;
- MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt),
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DILocation, Record[0],
+ (Context, Line, Column, Scope, InlinedAt)),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_GENERIC_DEBUG: {
+ if (Record.size() < 4)
+ return Error("Invalid record");
+
+ unsigned Tag = Record[1];
+ unsigned Version = Record[2];
+
+ if (Tag >= 1u << 16 || Version != 0)
+ return Error("Invalid record");
+
+ auto *Header = getMDString(Record[3]);
+ SmallVector<Metadata *, 8> DwarfOps;
+ 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(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);
@@ -1314,6 +2019,7 @@ std::error_code BitcodeReader::ParseMetadata() {
}
}
}
+#undef GET_OR_DISTINCT
}
/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
@@ -1359,10 +2065,13 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
if (ValID >= ValueList.size()) {
AliasInits.push_back(AliasInitWorklist.back());
} else {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- AliasInitWorklist.back().first->setAliasee(C);
- else
+ Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
+ if (!C)
return Error("Expected a constant");
+ GlobalAlias *Alias = AliasInitWorklist.back().first;
+ if (C->getType() != Alias->getType())
+ return Error("Alias and aliasee types don't match");
+ Alias->setAliasee(C);
}
AliasInitWorklist.pop_back();
}
@@ -1635,19 +2344,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<Constant*, 16> 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<SequentialType>(Elts[0]->getType()->getScalarType())
+ ->getElementType())
+ return Error("Explicit gep operator type does not match pointee type "
+ "of pointer operand");
+
ArrayRef<Constant *> 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#]
@@ -1917,6 +2636,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.
@@ -1967,7 +2712,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))
@@ -2021,6 +2767,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;
@@ -2139,21 +2891,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<PointerType>(Ty)->getAddressSpace();
- Ty = cast<PointerType>(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<PointerType>(Ty)->getAddressSpace();
+ Ty = cast<PointerType>(Ty)->getElementType();
+ }
- bool isConstant = Record[1];
- GlobalValue::LinkageTypes Linkage = getDecodedLinkage(Record[3]);
- unsigned Alignment = (1 << Record[4]) >> 1;
+ uint64_t RawLinkage = Record[3];
+ GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
+ 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())
@@ -2190,7 +2952,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (Record.size() > 10)
NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
else
- UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+ UpgradeDLLImportExportLinkage(NewGV, RawLinkage);
ValueList.push_back(NewGV);
@@ -2198,11 +2960,15 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (unsigned InitID = Record[2])
GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
- if (Record.size() > 11)
+ 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)) {
+ NewGV->setComdat(reinterpret_cast<Comdat *>(1));
+ }
break;
}
// FUNCTION: [type, callingconv, isproto, linkage, paramattr,
@@ -2214,10 +2980,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<FunctionType>(cast<PointerType>(Ty)->getElementType());
+ if (auto *PTy = dyn_cast<PointerType>(Ty))
+ Ty = PTy->getElementType();
+ auto *FTy = dyn_cast<FunctionType>(Ty);
if (!FTy)
return Error("Invalid type for value");
@@ -2226,10 +2991,14 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
bool isProto = Record[2];
- Func->setLinkage(getDecodedLinkage(Record[3]));
+ uint64_t RawLinkage = Record[3];
+ 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");
@@ -2240,7 +3009,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());
}
@@ -2254,13 +3023,17 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (Record.size() > 11)
Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
else
- UpgradeDLLImportExportLinkage(Func, Record[3]);
+ UpgradeDLLImportExportLinkage(Func, RawLinkage);
- if (Record.size() > 12)
+ 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)) {
+ Func->setComdat(reinterpret_cast<Comdat *>(1));
+ }
if (Record.size() > 13 && Record[13] != 0)
FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1));
@@ -2290,8 +3063,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())
@@ -2321,7 +3093,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())
@@ -2339,8 +3112,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);
@@ -2362,7 +3139,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();
@@ -2468,7 +3245,7 @@ ErrorOr<std::string> 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");
@@ -2494,8 +3271,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<MDNode>(MD));
+ }
+ continue;
+ }
+
+ // An instruction attachment.
Instruction *Inst = InstructionList[Record[0]];
for (unsigned i = 1; i != RecordLength; i = i+2) {
unsigned Kind = Record[i];
@@ -2518,6 +3308,20 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
}
}
+static std::error_code TypeCheckLoadStoreInst(DiagnosticHandlerFunction DH,
+ Type *ValType, Type *PtrType) {
+ if (!isa<PointerType>(PtrType))
+ return Error(DH, "Load/Store operand is not a pointer type");
+ Type *ElemType = cast<PointerType>(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))
@@ -2572,7 +3376,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:
@@ -2731,13 +3535,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<SequentialType>(BasePtr->getType()->getScalarType())
+ ->getElementType();
+ else if (Ty !=
+ cast<SequentialType>(BasePtr->getType()->getScalarType())
+ ->getElementType())
+ return Error(
+ "Explicit gep type does not match pointee type of pointer operand");
+
SmallVector<Value*, 16> GEPIdx;
while (OpNum != Record.size()) {
Value *Op;
@@ -2746,9 +3572,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<GetElementPtrInst>(I)->setIsInBounds(true);
break;
}
@@ -2760,13 +3587,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<unsigned, 4> 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);
@@ -2784,15 +3629,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<unsigned, 4> 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;
@@ -2846,6 +3712,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;
@@ -2854,8 +3722,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<VectorType>(Vec->getType())->getElementType(), Elt) ||
getValueTypePair(Record, OpNum, NextValueNo, Idx))
return Error("Invalid record");
@@ -2873,6 +3744,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;
@@ -3056,24 +3929,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<FunctionType>(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<PointerType>(Callee->getType());
- FunctionType *FTy = !CalleeTy ? nullptr :
- dyn_cast<FunctionType>(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<FunctionType>(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<Value*, 16> Ops;
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
@@ -3098,8 +3980,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops);
InstructionList.push_back(I);
- cast<InvokeInst>(I)->setCallingConv(
- static_cast<CallingConv::ID>(CCInfo));
+ cast<InvokeInst>(I)
+ ->setCallingConv(static_cast<CallingConv::ID>(~(1U << 13) & CCInfo));
cast<InvokeInst>(I)->setAttributes(PAL);
break;
}
@@ -3187,16 +4069,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<PointerType>(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<PointerType>(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);
@@ -3206,10 +4100,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<PointerType>(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;
}
@@ -3218,9 +4125,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<PointerType>(Op->getType())->getElementType();
+
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
if (Ordering == NotAtomic || Ordering == Release ||
Ordering == AcquireRelease)
@@ -3229,34 +4145,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<PointerType>(Ptr->getType())->getElementType(), Val) ||
- OpNum+2 != Record.size())
+ (BitCode == bitc::FUNC_CODE_INST_STORE
+ ? getValueTypePair(Record, OpNum, NextValueNo, Val)
+ : popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Val)) ||
+ OpNum + 2 != Record.size())
return Error("Invalid record");
- I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ 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<PointerType>(Ptr->getType())->getElementType(), Val) ||
- OpNum+4 != Record.size())
+ (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
+ ? getValueTypePair(Record, OpNum, NextValueNo, Val)
+ : popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(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)
@@ -3265,28 +4201,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<PointerType>(Ptr->getType())->getElementType(), Cmp) ||
- popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(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<PointerType>(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 =
@@ -3350,19 +4294,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<FunctionType>(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<PointerType>(Callee->getType());
- FunctionType *FTy = nullptr;
- if (OpTy) FTy = dyn_cast<FunctionType>(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<FunctionType>(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<Value*, 16> Args;
// Read the fixed params.
@@ -3389,7 +4345,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
}
- I = CallInst::Create(Callee, Args);
+ I = CallInst::Create(FTy, Callee, Args);
InstructionList.push_back(I);
cast<CallInst>(I)->setCallingConv(
static_cast<CallingConv::ID>((~(1U << 14) & CCInfo) >> 1));
@@ -3483,6 +4439,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<Function>(GV);
// If it's not a function or is already material, ignore the request.
if (!F || !F->isMaterializable())
@@ -3503,6 +4462,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) {
@@ -3533,7 +4495,7 @@ bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
return DeferredFunctionInfo.count(const_cast<Function*>(F));
}
-void BitcodeReader::Dematerialize(GlobalValue *GV) {
+void BitcodeReader::dematerialize(GlobalValue *GV) {
Function *F = dyn_cast<Function>(GV);
// If this function isn't dematerializable, this is a noop.
if (!F || !isDematerializable(F))
@@ -3546,10 +4508,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;
@@ -3690,7 +4655,8 @@ const std::error_category &llvm::BitcodeErrorCategory() {
static ErrorOr<Module *>
getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&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);
@@ -3702,7 +4668,8 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&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)
@@ -3717,9 +4684,10 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
ErrorOr<Module *>
llvm::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata) {
return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
- DiagnosticHandler);
+ DiagnosticHandler, ShouldLazyLoadMetadata);
}
ErrorOr<std::unique_ptr<Module>>
OpenPOWER on IntegriCloud