/// Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return getSubclassData(); }
+ /// Return true if either this is an opaque pointer type or if this pointee
+ /// type matches Ty. Primarily used for checking if an instruction's pointer
+ /// operands are valid types. Will be useless after non-opaque pointers are
+ /// removed.
+ bool isOpaqueOrPointeeTypeMatches(Type *Ty) {
+ return isOpaque() || PointeeTy == Ty;
+ }
+
/// Implement support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Type *T) {
return T->getTypeID() == PointerTyID;
Ordering == AtomicOrdering::AcquireRelease)
return error(Loc, "atomic load cannot use Release ordering");
- if (Ty != cast<PointerType>(Val->getType())->getElementType()) {
+ if (!cast<PointerType>(Val->getType())->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
ExplicitTypeLoc,
typeComparisonErrorMessage(
return error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return error(Loc, "store operand must be a first class value");
- if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Val->getType()))
return error(Loc, "stored value and pointer type do not match");
if (isAtomic && !Alignment)
return error(Loc, "atomic store must have explicit non-zero alignment");
Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
if (!isa<PointerType>(PtrType))
return error("Load/Store operand is not a pointer type");
- Type *ElemType = cast<PointerType>(PtrType)->getElementType();
- if (ValType && ValType != ElemType)
+ if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType))
return error("Explicit load/store type does not match pointee "
"type of pointer operand");
- if (!PointerType::isLoadableOrStorableType(ElemType))
+ if (!PointerType::isLoadableOrStorableType(ValType))
return error("Cannot load/store from pointer");
return Error::success();
}
Align Align, AtomicOrdering Order, SyncScope::ID SSID,
Instruction *InsertBef)
: UnaryInstruction(Ty, Load, Ptr, InsertBef) {
- assert(Ty == cast<PointerType>(Ptr->getType())->getElementType());
+ assert(cast<PointerType>(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty));
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SSID);
Align Align, AtomicOrdering Order, SyncScope::ID SSID,
BasicBlock *InsertAE)
: UnaryInstruction(Ty, Load, Ptr, InsertAE) {
- assert(Ty == cast<PointerType>(Ptr->getType())->getElementType());
+ assert(cast<PointerType>(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty));
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SSID);
assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
assert(getOperand(1)->getType()->isPointerTy() &&
"Ptr must have pointer type!");
- assert(getOperand(0)->getType() ==
- cast<PointerType>(getOperand(1)->getType())->getElementType()
- && "Ptr must be a pointer to Val type!");
+ assert(cast<PointerType>(getOperand(1)->getType())
+ ->isOpaqueOrPointeeTypeMatches(getOperand(0)->getType()) &&
+ "Ptr must be a pointer to Val type!");
assert(!(isAtomic() && getAlignment() == 0) &&
"Alignment required for atomic store");
}
void Verifier::visitStoreInst(StoreInst &SI) {
PointerType *PTy = dyn_cast<PointerType>(SI.getOperand(1)->getType());
Assert(PTy, "Store operand must be a pointer.", &SI);
- Type *ElTy = PTy->getElementType();
- Assert(ElTy == SI.getOperand(0)->getType(),
+ Type *ElTy = SI.getOperand(0)->getType();
+ Assert(PTy->isOpaqueOrPointeeTypeMatches(ElTy),
"Stored value type does not match pointer operand type!", &SI, ElTy);
Assert(SI.getAlignment() <= Value::MaximumAlignment,
"huge alignment values are unsupported", &SI);
%b = addrspacecast ptr addrspace(0) %a to ptr addrspace(2)
ret ptr addrspace(2) %b
}
+
+; CHECK: define i32 @load(ptr %a)
+; CHECK: %i = load i32, ptr %a
+; CHECK: ret i32 %i
+define i32 @load(ptr %a) {
+ %i = load i32, ptr %a
+ ret i32 %i
+}
+
+; CHECK: define void @store(ptr %a, i32 %i)
+; CHECK: store i32 %i, ptr %a
+; CHECK: ret void
+define void @store(ptr %a, i32 %i) {
+ store i32 %i, ptr %a
+ ret void
+}
--- /dev/null
+; RUN: opt -passes=verify -S < %s | FileCheck %s
+
+; CHECK: @load
+define i32 @load(ptr %a) {
+ %i = load i32, ptr %a
+ ret i32 %i
+}
+
+; CHECK: @store
+define void @store(ptr %a, i32 %i) {
+ store i32 %i, ptr %a
+ ret void
+}