void VerifyCallSite(CallSite CS);
void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
unsigned Count, ...);
- void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty,
+ void VerifyAttrs(Attributes Attrs, const Type *Ty,
bool isReturnValue, const Value *V);
- void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs,
+ void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs,
const Value *V);
void WriteValue(const Value *V) {
// VerifyAttrs - Check the given parameter attributes for an argument or return
// value of the specified type. The value V is printed in error messages.
-void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty,
+void Verifier::VerifyAttrs(Attributes Attrs, const Type *Ty,
bool isReturnValue, const Value *V) {
- if (Attrs == ParamAttr::None)
+ if (Attrs == Attribute::None)
return;
if (isReturnValue) {
- ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly;
- Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) +
+ Attributes RetI = Attrs & Attribute::ParameterOnly;
+ Assert1(!RetI, "Attribute " + Attribute::getAsString(RetI) +
" does not apply to return values!", V);
- } else {
- ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly;
- Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) +
- " only applies to return values!", V);
}
-
+ Attributes FnCheckAttr = Attrs & Attribute::FunctionOnly;
+ Assert1(!FnCheckAttr, "Attribute " + Attribute::getAsString(FnCheckAttr) +
+ " only applies to functions!", V);
+
for (unsigned i = 0;
- i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) {
- ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i];
+ i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
+ Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
Assert1(!(MutI & (MutI - 1)), "Attributes " +
- ParamAttr::getAsString(MutI) + " are incompatible!", V);
+ Attribute::getAsString(MutI) + " are incompatible!", V);
}
- ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty);
+ Attributes TypeI = Attrs & Attribute::typeIncompatible(Ty);
Assert1(!TypeI, "Wrong type for attribute " +
- ParamAttr::getAsString(TypeI), V);
+ Attribute::getAsString(TypeI), V);
- ParameterAttributes ByValI = Attrs & ParamAttr::ByVal;
+ Attributes ByValI = Attrs & Attribute::ByVal;
if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
Assert1(!ByValI || PTy->getElementType()->isSized(),
- "Attribute " + ParamAttr::getAsString(ByValI) +
+ "Attribute " + Attribute::getAsString(ByValI) +
" does not support unsized types!", V);
} else {
Assert1(!ByValI,
- "Attribute " + ParamAttr::getAsString(ByValI) +
+ "Attribute " + Attribute::getAsString(ByValI) +
" only applies to parameters with pointer type!", V);
}
}
// VerifyFunctionAttrs - Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::VerifyFunctionAttrs(const FunctionType *FT,
- const PAListPtr &Attrs,
+ const AttrListPtr &Attrs,
const Value *V) {
if (Attrs.isEmpty())
return;
bool SawNest = false;
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
- const ParamAttrsWithIndex &Attr = Attrs.getSlot(i);
+ const AttributeWithIndex &Attr = Attrs.getSlot(i);
const Type *Ty;
if (Attr.Index == 0)
VerifyAttrs(Attr.Attrs, Ty, Attr.Index == 0, V);
- if (Attr.Attrs & ParamAttr::Nest) {
+ if (Attr.Attrs & Attribute::Nest) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
- if (Attr.Attrs & ParamAttr::StructRet)
+ if (Attr.Attrs & Attribute::StructRet)
Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V);
}
+
+ Attributes FAttrs = Attrs.getFnAttributes();
+ Assert1(!(FAttrs & (~Attribute::FunctionOnly)),
+ "Attribute " + Attribute::getAsString(FAttrs) +
+ " does not apply to function!", V);
+
+ for (unsigned i = 0;
+ i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
+ Attributes MutI = FAttrs & Attribute::MutuallyIncompatible[i];
+ Assert1(!(MutI & (MutI - 1)), "Attributes " +
+ Attribute::getAsString(MutI) + " are incompatible!", V);
+ }
}
+static bool VerifyAttributeCount(const AttrListPtr &Attrs, unsigned Params) {
+ if (Attrs.isEmpty())
+ return true;
+
+ unsigned LastSlot = Attrs.getNumSlots() - 1;
+ unsigned LastIndex = Attrs.getSlot(LastSlot).Index;
+ if (LastIndex <= Params
+ || (LastIndex == (unsigned)~0
+ && (LastSlot == 0 || Attrs.getSlot(LastSlot - 1).Index <= Params)))
+ return true;
+
+ return false;
+}
// visitFunction - Verify that a function is ok.
//
void Verifier::visitFunction(Function &F) {
Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy,
"Invalid struct return type!", &F);
- const PAListPtr &Attrs = F.getParamAttrs();
+ const AttrListPtr &Attrs = F.getAttributes();
- Assert1(Attrs.isEmpty() ||
- Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(),
+ Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()),
"Attributes after last parameter!", &F);
// Check function attributes.
default:
break;
case CallingConv::C:
- case CallingConv::X86_SSECall:
break;
case CallingConv::Fast:
case CallingConv::Cold:
"Call parameter type does not match function signature!",
CS.getArgument(i), FTy->getParamType(i), I);
- const PAListPtr &Attrs = CS.getParamAttrs();
+ const AttrListPtr &Attrs = CS.getAttributes();
- Assert1(Attrs.isEmpty() ||
- Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(),
+ Assert1(VerifyAttributeCount(Attrs, CS.arg_size()),
"Attributes after last parameter!", I);
// Verify call attributes.
if (FTy->isVarArg())
// Check attributes on the varargs part.
for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) {
- ParameterAttributes Attr = Attrs.getParamAttrs(Idx);
+ Attributes Attr = Attrs.getParamAttributes(Idx);
VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I);
- ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible;
- Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) +
+ Attributes VArgI = Attr & Attribute::VarArgsIncompatible;
+ Assert1(!VArgI, "Attribute " + Attribute::getAsString(VArgI) +
" cannot be used for vararg call arguments!", I);
}
case Intrinsic::gcwrite:
case Intrinsic::gcread:
if (ID == Intrinsic::gcroot) {
- Assert1(isa<AllocaInst>(CI.getOperand(1)->stripPointerCasts()),
- "llvm.gcroot parameter #1 must be an alloca.", &CI);
+ AllocaInst *AI =
+ dyn_cast<AllocaInst>(CI.getOperand(1)->stripPointerCasts());
+ Assert1(AI && isa<PointerType>(AI->getType()->getElementType()),
+ "llvm.gcroot parameter #1 must be a pointer alloca.", &CI);
Assert1(isa<Constant>(CI.getOperand(2)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
}
"llvm.init_trampoline parameter #2 must resolve to a function.",
&CI);
break;
+ case Intrinsic::prefetch:
+ Assert1(isa<ConstantInt>(CI.getOperand(2)) &&
+ isa<ConstantInt>(CI.getOperand(3)) &&
+ cast<ConstantInt>(CI.getOperand(2))->getZExtValue() < 2 &&
+ cast<ConstantInt>(CI.getOperand(3))->getZExtValue() < 4,
+ "invalid arguments to llvm.prefetch",
+ &CI);
+ break;
}
}
}
// Check parameter attributes.
- Assert1(F->getParamAttrs() == Intrinsic::getParamAttrs(ID),
+ Assert1(F->getAttributes() == Intrinsic::getAttributes(ID),
"Intrinsic has wrong parameter attributes!", F);
}