return false;
if (const auto *PtrT = dyn_cast<PointerType>(V->getType()))
- return PtrT->getPointerElementType()->isSized();
+ return PtrT->isOpaque() ||
+ PtrT->getNonOpaquePointerElementType()->isSized();
return false;
};
auto Make = [](ArrayRef<Value *>, ArrayRef<Type *> Ts) {
OpDescriptor llvm::fuzzerop::gepDescriptor(unsigned Weight) {
auto buildGEP = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
- Type *Ty = Srcs[0]->getType()->getPointerElementType();
- auto Indices = makeArrayRef(Srcs).drop_front(1);
+ // TODO: It would be better to generate a random type here, rather than
+ // generating a random value and picking its type.
+ Type *Ty = Srcs[0]->getType()->isOpaquePointerTy()
+ ? Srcs[1]->getType()
+ : Srcs[0]->getType()->getNonOpaquePointerElementType();
+ auto Indices = makeArrayRef(Srcs).drop_front(2);
return GetElementPtrInst::Create(Ty, Srcs[0], Indices, "G", Inst);
};
// TODO: Handle aggregates and vectors
// TODO: Support multiple indices.
// TODO: Try to avoid meaningless accesses.
- return {Weight, {sizedPtrType(), anyIntType()}, buildGEP};
+ SourcePred sizedType(
+ [](ArrayRef<Value *>, const Value *V) { return V->getType()->isSized(); },
+ None);
+ return {Weight, {sizedPtrType(), sizedType, anyIntType()}, buildGEP};
}
static uint64_t getAggregateNumElements(Type *T) {
IP = ++I->getIterator();
assert(IP != BB.end() && "guaranteed by the findPointer");
}
- auto *NewLoad =
- new LoadInst(Ptr->getType()->getPointerElementType(), Ptr, "L", &*IP);
+ // For opaque pointers, pick the type independently.
+ Type *AccessTy = Ptr->getType()->isOpaquePointerTy()
+ ? RS.getSelection()->getType()
+ : Ptr->getType()->getNonOpaquePointerElementType();
+ auto *NewLoad = new LoadInst(AccessTy, Ptr, "L", &*IP);
// Only sample this load if it really matches the descriptor
if (Pred.matches(Srcs, NewLoad))
if (Inst->isTerminator())
return false;
- if (auto PtrTy = dyn_cast<PointerType>(Inst->getType())) {
+ if (auto *PtrTy = dyn_cast<PointerType>(Inst->getType())) {
+ if (PtrTy->isOpaque())
+ return true;
+
// We can never generate loads from non first class or non sized types
- Type *ElemTy = PtrTy->getPointerElementType();
+ Type *ElemTy = PtrTy->getNonOpaquePointerElementType();
if (!ElemTy->isSized() || !ElemTy->isFirstClassType())
return false;