[Bitcode] Check for type mismatch when assigning value

If the value is forward-declared, then the type must match,
otherwise we can't RAUW.
This commit is contained in:
Nikita Popov 2022-03-11 12:10:00 +01:00
parent fbbc41f8dd
commit cda82d39f3
5 changed files with 26 additions and 11 deletions

View File

@ -2511,9 +2511,10 @@ Error BitcodeReader::parseConstants() {
SmallVector<int, 16> Mask;
ShuffleVectorInst::getShuffleMask(Op2, Mask);
Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
ValueList.assignValue(
if (Error Err = ValueList.assignValue(
CstNo, V,
getVirtualTypeID(V->getType(), getContainedTypeID(OpTyID)));
getVirtualTypeID(V->getType(), getContainedTypeID(OpTyID))))
return Err;
}
for (auto &DelayedSelector : DelayedSelectors) {
Type *OpTy = DelayedSelector.OpTy;
@ -2539,7 +2540,8 @@ Error BitcodeReader::parseConstants() {
Constant *Op0 =
ValueList.getConstantFwdRef(Op0Idx, SelectorTy, SelectorTyID);
Value *V = ConstantExpr::getSelect(Op0, Op1, Op2);
ValueList.assignValue(CstNo, V, OpTyID);
if (Error Err = ValueList.assignValue(CstNo, V, OpTyID))
return Err;
}
if (NextCstNo != ValueList.size())
@ -3146,7 +3148,8 @@ Error BitcodeReader::parseConstants() {
}
assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID");
ValueList.assignValue(NextCstNo, V, CurTyID);
if (Error Err = ValueList.assignValue(NextCstNo, V, CurTyID))
return Err;
++NextCstNo;
}
}
@ -5880,7 +5883,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (!I->getType()->isVoidTy()) {
assert(I->getType() == getTypeByID(ResTypeID) &&
"Incorrect result type ID");
ValueList.assignValue(NextValueNo++, I, ResTypeID);
if (Error Err = ValueList.assignValue(NextValueNo++, I, ResTypeID))
return Err;
}
}

View File

@ -17,6 +17,7 @@
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstddef>
@ -60,11 +61,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
} // end namespace llvm
void BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
unsigned TypeID) {
if (Idx == size()) {
push_back(V, TypeID);
return;
return Error::success();
}
if (Idx >= size())
@ -74,7 +75,7 @@ void BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
if (!Old.first) {
Old.first = V;
Old.second = TypeID;
return;
return Error::success();
}
// Handle constants and non-constants (e.g. instrs) differently for
@ -86,9 +87,14 @@ void BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
} else {
// If there was a forward reference to this value, replace it.
Value *PrevVal = Old.first;
if (PrevVal->getType() != V->getType())
return createStringError(
std::errc::illegal_byte_sequence,
"Assigned value does not match type of forward declaration");
Old.first->replaceAllUsesWith(V);
PrevVal->deleteValue();
}
return Error::success();
}
Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty,

View File

@ -21,6 +21,7 @@
namespace llvm {
class Constant;
class Error;
class LLVMContext;
class Type;
class Value;
@ -92,7 +93,7 @@ public:
Constant *getConstantFwdRef(unsigned Idx, Type *Ty, unsigned TyID);
Value *getValueFwdRef(unsigned Idx, Type *Ty, unsigned TyID);
void assignValue(unsigned Idx, Value *V, unsigned TypeID);
Error assignValue(unsigned Idx, Value *V, unsigned TypeID);
/// Once all constants are read, this method bulk resolves any forward
/// references.

Binary file not shown.

View File

@ -296,3 +296,7 @@ RUN: not llvm-dis -disable-output -opaque-pointers %p/Inputs/missing-element-typ
RUN: FileCheck --check-prefix=MISSING-ELEMENT-TYPE-FOR-ATTRIBUTE %s
MISSING-ELEMENT-TYPE-FOR-ATTRIBUTE: Missing element type for typed attribute upgrade
RUN: not llvm-dis -disable-output -opaque-pointers %p/Inputs/invalid-forward-declare.bc 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-FORWARD-DECLARE %s
INVALID-FORWARD-DECLARE: Assigned value does not match type of forward declaration