diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -493,6 +493,7 @@ std::vector GCTable; std::vector TypeList; + DenseMap ElementTypes; DenseMap FunctionTypes; BitcodeReaderValueList ValueList; Optional MDLoader; @@ -595,6 +596,8 @@ Type *getTypeByID(unsigned ID); + Type *getElementType(Type *Ty); + Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); @@ -1174,6 +1177,13 @@ return TypeList[ID] = createIdentifiedStructType(Context); } +Type *BitcodeReader::getElementType(Type *Ty) { + auto Ret = ElementTypes.find(Ty); + if (Ret == ElementTypes.end()) + return nullptr; + return Ret->second; +} + StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context, StringRef Name) { auto *Ret = StructType::create(Context, Name); @@ -1771,11 +1781,11 @@ unsigned AddressSpace = 0; if (Record.size() == 2) AddressSpace = Record[1]; - ResultTy = getTypeByID(Record[0]); - if (!ResultTy || - !PointerType::isValidElementType(ResultTy)) + Type *ElementTy = getTypeByID(Record[0]); + if (!ElementTy || !PointerType::isValidElementType(ElementTy)) return error("Invalid type"); - ResultTy = PointerType::get(ResultTy, AddressSpace); + ResultTy = PointerType::get(ElementTy, AddressSpace); + ElementTypes[ResultTy] = ElementTy; break; } case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace] @@ -2652,11 +2662,11 @@ SmallVector Elts; Type *Elt0FullTy = nullptr; while (OpNum != Record.size()) { - if (!Elt0FullTy) - Elt0FullTy = getTypeByID(Record[OpNum]); Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return error("Invalid record"); + if (!Elt0FullTy) + Elt0FullTy = ElTy; Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } @@ -2664,9 +2674,11 @@ return error("Invalid gep with no operands"); PointerType *OrigPtrTy = cast(Elt0FullTy->getScalarType()); - if (!PointeeType) - PointeeType = OrigPtrTy->getElementType(); - else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) + if (!PointeeType) { + PointeeType = getElementType(OrigPtrTy); + if (!PointeeType) + return error("Missing pointee type"); + } else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType)) return error("Explicit gep operator type does not match pointee type " "of pointer operand"); @@ -2797,9 +2809,11 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - V = InlineAsm::get( - cast(cast(CurTy)->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + Type *ElTy = getElementType(CurTy); + if (!ElTy) + return error("Missing pointee type"); + V = InlineAsm::get(cast(ElTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., @@ -2823,10 +2837,12 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - V = InlineAsm::get( - cast(cast(CurTy)->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, - InlineAsm::AsmDialect(AsmDialect)); + Type *ElTy = getElementType(CurTy); + if (!ElTy) + return error("Missing pointee type"); + V = InlineAsm::get(cast(ElTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect)); break; } // This version adds support for the unwind keyword. @@ -2850,10 +2866,12 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3 + AsmStrSize + i]; UpgradeInlineAsmString(&AsmStr); - V = InlineAsm::get( - cast(cast(CurTy)->getElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, - InlineAsm::AsmDialect(AsmDialect), CanThrow); + Type *ElTy = getElementType(CurTy); + if (!ElTy) + return error("Missing pointee type"); + V = InlineAsm::get(cast(ElTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect), CanThrow); break; } case bitc::CST_CODE_BLOCKADDRESS:{ @@ -3203,7 +3221,9 @@ if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast(Ty)->getAddressSpace(); - Ty = cast(Ty)->getElementType(); + Ty = getElementType(Ty); + if (!Ty) + return error("Missing pointee type"); } uint64_t RawLinkage = Record[3]; @@ -3295,8 +3315,11 @@ Type *FTy = getTypeByID(Record[0]); if (!FTy) return error("Invalid record"); - if (auto *PTy = dyn_cast(FTy)) - FTy = PTy->getElementType(); + if (auto *PTy = dyn_cast(FTy)) { + FTy = getElementType(PTy); + if (!FTy) + return error("Missing pointee type"); + } if (!isa(FTy)) return error("Invalid type for value"); @@ -3334,7 +3357,9 @@ Func->removeParamAttr(i, Kind); Type *PTy = cast(FTy)->getParamType(i); - Type *PtrEltTy = cast(PTy)->getElementType(); + Type *PtrEltTy = getElementType(PTy); + if (!PtrEltTy) + return error("Missing pointee type"); Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -3452,7 +3477,9 @@ auto *PTy = dyn_cast(Ty); if (!PTy) return error("Invalid type for value"); - Ty = PTy->getElementType(); + Ty = getElementType(PTy); + if (!Ty) + return error("Missing pointee type"); AddrSpace = PTy->getAddressSpace(); } else { AddrSpace = Record[OpNum++]; @@ -3815,7 +3842,8 @@ CB->removeParamAttr(i, Kind); - Type *PtrEltTy = cast(ArgsTys[i])->getElementType(); + Type *PtrEltTy = getElementType(ArgsTys[i]); + assert(PtrEltTy && "Missing pointee type"); Attribute NewAttr; switch (Kind) { case Attribute::ByVal: @@ -4116,8 +4144,9 @@ return error("Invalid record"); if (!Ty) { - Ty = cast(BasePtr->getType()->getScalarType()) - ->getElementType(); + Ty = getElementType(BasePtr->getType()->getScalarType()); + if (!Ty) + return error("Missing pointee type"); } else if (!cast(BasePtr->getType()->getScalarType()) ->isOpaqueOrPointeeTypeMatches(Ty)) { return error( @@ -4634,8 +4663,7 @@ if (!CalleeTy) return error("Callee is not a pointer"); if (!FTy) { - FTy = dyn_cast( - cast(Callee->getType())->getElementType()); + FTy = dyn_cast(getElementType(Callee->getType())); if (!FTy) return error("Callee is not of pointer to function type"); } else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy)) @@ -4714,12 +4742,14 @@ PointerType *OpTy = dyn_cast(Callee->getType()); if (!OpTy) return error("Callee is not a pointer type"); + Type *ElTy = getElementType(Callee->getType()); + if (!ElTy) + return error("Missing pointee type"); if (!FTy) { - FTy = dyn_cast( - cast(Callee->getType())->getElementType()); + FTy = dyn_cast(ElTy); if (!FTy) return error("Callee is not of pointer to function type"); - } else if (cast(Callee->getType())->getElementType() != FTy) + } else if (ElTy != FTy) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) @@ -4873,7 +4903,9 @@ auto *PTy = dyn_cast_or_null(Ty); if (!PTy) return error("Old-style alloca with a non-pointer type"); - Ty = PTy->getElementType(); + Ty = getElementType(PTy); + if (!Ty) + return error("Missing pointee type"); } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); @@ -4916,7 +4948,9 @@ if (OpNum + 3 == Record.size()) { Ty = getTypeByID(Record[OpNum++]); } else { - Ty = cast(Op->getType())->getElementType(); + Ty = getElementType(Op->getType()); + if (!Ty) + return error("Missing pointee type"); } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) @@ -4949,7 +4983,9 @@ if (OpNum + 5 == Record.size()) { Ty = getTypeByID(Record[OpNum++]); } else { - Ty = cast(Op->getType())->getElementType(); + Ty = getElementType(Op->getType()); + if (!Ty) + return error("Missing pointee type"); } if (Error Err = typeCheckLoadStoreInst(Ty, Op->getType())) @@ -4977,12 +5013,17 @@ 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) || - (BitCode == bitc::FUNC_CODE_INST_STORE + Type *PointeeTy; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr)) + return error("Invalid record"); + if (BitCode == bitc::FUNC_CODE_INST_STORE_OLD) { + PointeeTy = getElementType(Ptr->getType()); + if (!PointeeTy) + return error("Missing pointee type"); + } + if ((BitCode == bitc::FUNC_CODE_INST_STORE ? getValueTypePair(Record, OpNum, NextValueNo, Val) - : popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), - Val)) || + : popValue(Record, OpNum, NextValueNo, PointeeTy, Val)) || OpNum + 2 != Record.size()) return error("Invalid record"); @@ -5006,12 +5047,17 @@ unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - !isa(Ptr->getType()) || - (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC + !isa(Ptr->getType())) + return error("Invalid record"); + Type *PointeeTy; + if (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC_OLD) { + PointeeTy = getElementType(Ptr->getType()); + if (!PointeeTy) + return error("Missing pointee type"); + } + if ((BitCode == bitc::FUNC_CODE_INST_STOREATOMIC ? getValueTypePair(Record, OpNum, NextValueNo, Val) - : popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), - Val)) || + : popValue(Record, OpNum, NextValueNo, PointeeTy, Val)) || OpNum + 4 != Record.size()) return error("Invalid record"); @@ -5262,8 +5308,7 @@ if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FTy = dyn_cast( - cast(Callee->getType())->getElementType()); + FTy = dyn_cast(getElementType(Callee->getType())); if (!FTy) return error("Callee is not of pointer to function type"); } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))