Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -483,7 +483,8 @@ std::vector SectionTable; std::vector GCTable; - std::vector TypeList; + std::vector TypeList; + std::vector ElementTypeList; DenseMap FunctionTypes; BitcodeReaderValueList ValueList; Optional MDLoader; @@ -591,6 +592,7 @@ StructType *createIdentifiedStructType(LLVMContext &Context); Type *getTypeByID(unsigned ID); + Type *getElementTypeByID(unsigned ID); Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) @@ -1176,6 +1178,23 @@ return TypeList[ID] = createIdentifiedStructType(Context); } +Type *BitcodeReader::getElementTypeByID(unsigned ID) { + if (ID >= TypeList.size()) + return nullptr; + + Type *Ty = TypeList[ID]; + if (!Ty->isPointerTy()) + return nullptr; + + Type *ElemTy = ElementTypeList[ID]; + if (!ElemTy) + return nullptr; + + assert(cast(Ty)->isOpaqueOrPointeeTypeMatches(ElemTy) && + "Incorrect element type"); + return ElemTy; +} + StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context, StringRef Name) { auto *Ret = StructType::create(Context, Name); @@ -1708,6 +1727,7 @@ // Read a record. Record.clear(); Type *ResultTy = nullptr; + Type *ElemTy = nullptr; Expected MaybeRecord = Stream.readRecord(Entry.ID, Record); if (!MaybeRecord) return MaybeRecord.takeError(); @@ -1720,6 +1740,7 @@ if (Record.empty()) return error("Invalid record"); TypeList.resize(Record[0]); + ElementTypeList.resize(Record[0]); continue; case bitc::TYPE_CODE_VOID: // VOID ResultTy = Type::getVoidTy(Context); @@ -1782,6 +1803,7 @@ if (!ResultTy || !PointerType::isValidElementType(ResultTy)) return error("Invalid type"); + ElemTy = ResultTy; ResultTy = PointerType::get(ResultTy, AddressSpace); break; } @@ -1932,7 +1954,9 @@ return error( "Invalid TYPE table: Only named structs can be forward referenced"); assert(ResultTy && "Didn't read a type?"); - TypeList[NumRecords++] = ResultTy; + TypeList[NumRecords] = ResultTy; + ElementTypeList[NumRecords] = ElemTy; + ++NumRecords; } } @@ -2343,6 +2367,7 @@ // Read all the records for this value table. Type *CurTy = Type::getInt32Ty(Context); + Type *CurElemTy = nullptr; unsigned NextCstNo = ValueList.size(); struct DelayedShufTy { @@ -2454,6 +2479,7 @@ if (TypeList[Record[0]] == VoidType) return error("Invalid constant type"); CurTy = TypeList[Record[0]]; + CurElemTy = getElementTypeByID(Record[0]); continue; // Skip the ValueList manipulation. case bitc::CST_CODE_NULL: // NULL if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy()) @@ -2824,9 +2850,10 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack); break; } // This version adds support for the asm dialect keywords (e.g., @@ -2850,9 +2877,10 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect)); break; } @@ -2881,9 +2909,10 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[OpNum + AsmStrSize + i]; UpgradeInlineAsmString(&AsmStr); - // FIXME: support upgrading in opaque pointers mode. - V = InlineAsm::get(cast(CurTy->getPointerElementType()), - AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + if (!CurElemTy) + return error("Missing element type for old-style inlineasm"); + V = InlineAsm::get(cast(CurElemTy), AsmStr, ConstrStr, + HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect), CanThrow); break; } @@ -3279,7 +3308,9 @@ if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast(Ty)->getAddressSpace(); - Ty = Ty->getPointerElementType(); + Ty = getElementTypeByID(Record[0]); + if (!Ty) + return error("Missing element type for old-style global"); } uint64_t RawLinkage = Record[3]; @@ -3371,8 +3402,11 @@ Type *FTy = getTypeByID(Record[0]); if (!FTy) return error("Invalid record"); - if (auto *PTy = dyn_cast(FTy)) - FTy = PTy->getPointerElementType(); + if (isa(FTy)) { + FTy = getElementTypeByID(Record[0]); + if (!FTy) + return error("Missing element type for old-style function"); + } if (!isa(FTy)) return error("Invalid type for value"); @@ -3527,7 +3561,8 @@ if (Record.size() < (3 + (unsigned)NewRecord)) return error("Invalid record"); unsigned OpNum = 0; - Type *Ty = getTypeByID(Record[OpNum++]); + unsigned TypeID = Record[OpNum++]; + Type *Ty = getTypeByID(TypeID); if (!Ty) return error("Invalid record"); @@ -3536,8 +3571,10 @@ auto *PTy = dyn_cast(Ty); if (!PTy) return error("Invalid type for value"); - Ty = PTy->getPointerElementType(); AddrSpace = PTy->getAddressSpace(); + Ty = getElementTypeByID(TypeID); + if (!Ty) + return error("Missing element type for old-style indirect symbol"); } else { AddrSpace = Record[OpNum++]; } @@ -4993,10 +5030,9 @@ const bool SwiftError = Bitfield::get(Rec); Type *Ty = getTypeByID(Record[0]); if (!Bitfield::get(Rec)) { - auto *PTy = dyn_cast_or_null(Ty); - if (!PTy) - return error("Old-style alloca with a non-pointer type"); - Ty = PTy->getPointerElementType(); + Ty = getElementTypeByID(Record[0]); + if (!Ty) + return error("Missing element type for old-style alloca"); } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); Index: llvm/test/Bitcode/aggregateInstructions.3.2.ll =================================================================== --- llvm/test/Bitcode/aggregateInstructions.3.2.ll +++ llvm/test/Bitcode/aggregateInstructions.3.2.ll @@ -1,4 +1,5 @@ -; RUN: llvm-dis < %s.bc| FileCheck %s +; RUN: llvm-dis -opaque-pointers=0 < %s.bc| FileCheck %s +; RUN: llvm-dis -opaque-pointers=1 < %s.bc| FileCheck %s ; RUN: verify-uselistorder < %s.bc ; aggregateOperations.3.2.ll.bc was generated by passing this file to llvm-as-3.2.