X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.cpp;h=4044ac80f20330b3de2a72881f5145269b097b5f;hb=3b821159da170b233a3ba8c12ce47ee6662946f0;hp=09e3e75f99d7de744ce588a6b39bb2734f4fac4a;hpb=4eeb5e9c6920d847dacfc5631131466882c504d5;p=oota-llvm.git diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 09e3e75f99d..4044ac80f20 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -63,9 +63,7 @@ public: // vector compatibility methods unsigned size() const { return ValuePtrs.size(); } void resize(unsigned N) { ValuePtrs.resize(N); } - void push_back(Value *V) { - ValuePtrs.push_back(V); - } + void push_back(Value *V) { ValuePtrs.emplace_back(V); } void clear() { assert(ResolveConstants.empty() && "Constants not resolved?"); @@ -230,7 +228,7 @@ public: DiagnosticHandlerFunction DiagnosticHandler); explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C, DiagnosticHandlerFunction DiagnosticHandler); - ~BitcodeReader() { FreeState(); } + ~BitcodeReader() override { FreeState(); } std::error_code materializeForwardReferencedFunctions(); @@ -240,9 +238,9 @@ public: bool isDematerializable(const GlobalValue *GV) const override; std::error_code materialize(GlobalValue *GV) override; - std::error_code MaterializeModule(Module *M) override; + std::error_code materializeModule(Module *M) override; std::vector getIdentifiedStructTypes() const override; - void Dematerialize(GlobalValue *GV) override; + void dematerialize(GlobalValue *GV) override; /// @brief Main interface to parsing a bitcode buffer. /// @returns true if an error occurred. @@ -299,9 +297,9 @@ private: // have. ResVal = getFnValueByID(ValNo, nullptr); return ResVal == nullptr; - } else if (Slot == Record.size()) { - return true; } + if (Slot == Record.size()) + return true; unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); @@ -370,7 +368,7 @@ private: std::error_code GlobalCleanup(); std::error_code ResolveGlobalAndAliasInits(); std::error_code ParseMetadata(); - std::error_code ParseMetadataAttachment(); + std::error_code ParseMetadataAttachment(Function &F); ErrorOr parseModuleTriple(); std::error_code ParseUseLists(); std::error_code InitStream(); @@ -401,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); } @@ -607,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; } } @@ -764,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); } @@ -775,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; } @@ -1068,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: @@ -1098,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: @@ -1214,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"); @@ -1339,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; @@ -1370,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; } @@ -1453,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; } @@ -1598,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(); @@ -1702,7 +1738,7 @@ std::error_code BitcodeReader::ParseMetadata() { Metadata *InlinedAt = Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr; MDValueList.AssignValue( - GET_OR_DISTINCT(MDLocation, Record[0], + GET_OR_DISTINCT(DILocation, Record[0], (Context, Line, Column, Scope, InlinedAt)), NextMDValueNo++); break; @@ -1722,7 +1758,7 @@ 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; @@ -1732,7 +1768,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDSubrange, Record[0], + GET_OR_DISTINCT(DISubrange, Record[0], (Context, Record[1], unrotateSign(Record[2]))), NextMDValueNo++); break; @@ -1741,7 +1777,7 @@ std::error_code BitcodeReader::ParseMetadata() { if (Record.size() != 3) return Error("Invalid record"); - MDValueList.AssignValue(GET_OR_DISTINCT(MDEnumerator, Record[0], + MDValueList.AssignValue(GET_OR_DISTINCT(DIEnumerator, Record[0], (Context, unrotateSign(Record[1]), getMDString(Record[2]))), NextMDValueNo++); @@ -1752,7 +1788,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDBasicType, Record[0], + GET_OR_DISTINCT(DIBasicType, Record[0], (Context, Record[1], getMDString(Record[2]), Record[3], Record[4], Record[5])), NextMDValueNo++); @@ -1763,7 +1799,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDDerivedType, Record[0], + GET_OR_DISTINCT(DIDerivedType, Record[0], (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), Record[4], getMDOrNull(Record[5]), getMDOrNull(Record[6]), @@ -1777,7 +1813,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDCompositeType, Record[0], + GET_OR_DISTINCT(DICompositeType, Record[0], (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), Record[4], getMDOrNull(Record[5]), getMDOrNull(Record[6]), @@ -1793,7 +1829,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDSubroutineType, Record[0], + GET_OR_DISTINCT(DISubroutineType, Record[0], (Context, Record[1], getMDOrNull(Record[2]))), NextMDValueNo++); break; @@ -1803,24 +1839,25 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDFile, Record[0], (Context, getMDString(Record[1]), + GET_OR_DISTINCT(DIFile, Record[0], (Context, getMDString(Record[1]), getMDString(Record[2]))), NextMDValueNo++); break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() != 14) + if (Record.size() < 14 || Record.size() > 15) return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDCompileUnit, Record[0], + 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]))), + getMDOrNull(Record[13]), + Record.size() == 14 ? 0 : Record[14])), NextMDValueNo++); break; } @@ -1830,7 +1867,7 @@ std::error_code BitcodeReader::ParseMetadata() { MDValueList.AssignValue( GET_OR_DISTINCT( - MDSubprogram, Record[0], + 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], @@ -1845,7 +1882,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDLexicalBlock, Record[0], + GET_OR_DISTINCT(DILexicalBlock, Record[0], (Context, getMDOrNull(Record[1]), getMDOrNull(Record[2]), Record[3], Record[4])), NextMDValueNo++); @@ -1856,7 +1893,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDLexicalBlockFile, Record[0], + GET_OR_DISTINCT(DILexicalBlockFile, Record[0], (Context, getMDOrNull(Record[1]), getMDOrNull(Record[2]), Record[3])), NextMDValueNo++); @@ -1867,7 +1904,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDNamespace, Record[0], + GET_OR_DISTINCT(DINamespace, Record[0], (Context, getMDOrNull(Record[1]), getMDOrNull(Record[2]), getMDString(Record[3]), Record[4])), @@ -1878,7 +1915,7 @@ std::error_code BitcodeReader::ParseMetadata() { if (Record.size() != 3) return Error("Invalid record"); - MDValueList.AssignValue(GET_OR_DISTINCT(MDTemplateTypeParameter, + MDValueList.AssignValue(GET_OR_DISTINCT(DITemplateTypeParameter, Record[0], (Context, getMDString(Record[1]), getMDOrNull(Record[2]))), @@ -1890,7 +1927,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDTemplateValueParameter, Record[0], + GET_OR_DISTINCT(DITemplateValueParameter, Record[0], (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), getMDOrNull(Record[4]))), NextMDValueNo++); @@ -1901,7 +1938,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDGlobalVariable, Record[0], + GET_OR_DISTINCT(DIGlobalVariable, Record[0], (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], @@ -1911,15 +1948,16 @@ std::error_code BitcodeReader::ParseMetadata() { break; } case bitc::METADATA_LOCAL_VAR: { - if (Record.size() != 10) + // 10th field is for the obseleted 'inlinedAt:' field. + if (Record.size() != 9 && Record.size() != 10) return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDLocalVariable, Record[0], + 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], getMDOrNull(Record[9]))), + Record[8])), NextMDValueNo++); break; } @@ -1928,7 +1966,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDExpression, Record[0], + GET_OR_DISTINCT(DIExpression, Record[0], (Context, makeArrayRef(Record).slice(1))), NextMDValueNo++); break; @@ -1938,7 +1976,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDObjCProperty, Record[0], + GET_OR_DISTINCT(DIObjCProperty, Record[0], (Context, getMDString(Record[1]), getMDOrNull(Record[2]), Record[3], getMDString(Record[4]), getMDString(Record[5]), @@ -1951,7 +1989,7 @@ std::error_code BitcodeReader::ParseMetadata() { return Error("Invalid record"); MDValueList.AssignValue( - GET_OR_DISTINCT(MDImportedEntity, Record[0], + GET_OR_DISTINCT(DIImportedEntity, Record[0], (Context, Record[1], getMDOrNull(Record[2]), getMDOrNull(Record[3]), Record[4], getMDString(Record[5]))), @@ -2313,14 +2351,17 @@ std::error_code BitcodeReader::ParseConstants() { Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } - ArrayRef Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(Elts[0], Indices, - BitCode == - bitc::CST_CODE_CE_INBOUNDS_GEP); if (PointeeType && - PointeeType != cast(V)->getSourceElementType()) + 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(PointeeType, Elts[0], Indices, + BitCode == + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] @@ -2853,12 +2894,18 @@ 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"); - 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; @@ -2910,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)) { @@ -2927,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"); @@ -2957,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()); } @@ -2975,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)) { @@ -3010,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()) @@ -3060,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); @@ -3189,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"); @@ -3215,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]; @@ -3239,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)) @@ -3293,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: @@ -3472,10 +3550,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return Error("Invalid record"); - if (Ty && - Ty != - cast(BasePtr->getType()->getScalarType()) - ->getElementType()) + 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"); @@ -3502,10 +3582,13 @@ 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; Type *CurTy = Agg->getType(); - for (unsigned RecSize = Record.size(); - OpNum != RecSize; ++OpNum) { + for (; OpNum != RecSize; ++OpNum) { bool IsArray = CurTy->isArrayTy(); bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; @@ -3541,18 +3624,19 @@ 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; Type *CurTy = Agg->getType(); - for (unsigned RecSize = Record.size(); - OpNum != RecSize; ++OpNum) { + 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 (!CurTy->isStructTy() && !CurTy->isArrayTy()) - return Error("Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); if (IsStruct && Index >= CurTy->subtypes().size()) @@ -3567,6 +3651,9 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { 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; @@ -3620,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; @@ -3628,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"); @@ -3647,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; @@ -3830,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) { @@ -3872,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; } @@ -3961,21 +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])); - Type *OpTy = getTypeByID(Record[1]); - Value *Size = getFnValueByID(Record[2], OpTy); 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 Align; if (std::error_code EC = - parseAlignmentValue(AlignRecord & ~InAllocaMask, Align)) { + parseAlignmentValue(AlignRecord & ~FlagMask, Align)) { return EC; } if (!Ty || !Size) return Error("Invalid record"); - AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, Align); + AllocaInst *AI = new AllocaInst(Ty, Size, Align); AI->setUsedWithInAlloca(InAlloca); I = AI; InstructionList.push_back(I); @@ -3991,15 +4101,16 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { 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(Op, "", Record[OpNum+1], Align); - - if (Ty && Ty != I->getType()) - return Error("Explicit load type does not match pointee type of " - "pointer operand"); + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align); InstructionList.push_back(I); break; @@ -4015,6 +4126,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { 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 || @@ -4029,21 +4145,25 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return EC; I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); - (void)Ty; - assert((!Ty || Ty == I->getType()) && - "Explicit type doesn't match pointee type of the first operand"); - 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()) + (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; @@ -4051,16 +4171,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { 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) @@ -4076,23 +4203,29 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { 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 = @@ -4156,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. @@ -4195,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)); @@ -4345,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)) @@ -4358,7 +4503,7 @@ 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.");