summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-04-18 20:15:25 +0000
committerBill Wendling <isanbard@gmail.com>2013-04-18 20:15:25 +0000
commitbb1b63c48397a3bac5d00f2ac9d33cc14efd714c (patch)
treefd01da2199225cea17f87952fc4a790e8d897f41 /lib
parent4b15d6ae49b407cfcf526a3f7bec7ab15fa803c0 (diff)
This patch addresses two cleanup issues:
1. Verify::VerifyParameterAttrs in "lib/IR/Verifier.cpp" and AttrBuilder::removeFunctionOnlyAttrs in "lib/IR/Attributes.cpp" (only called by Verify::VerifyFunctionAttrs) separately maintained a list of function-only attribute types. I've consolidated the logic into a new function used for both cases in "lib/IR/Verifier.cpp", so this logic is in one place (other than the AsmParser front-end) 2. Various functions in "lib/IR/Verifier.cpp" passed AttributeSet around by reference needlessly, as it's just a handle to an immutable pimpl body. Patch by Stephen Lin! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179790 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/IR/Attributes.cpp27
-rw-r--r--lib/IR/Verifier.cpp152
2 files changed, 71 insertions, 108 deletions
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index b513f7dc84c..f434b8e8c35 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -1115,33 +1115,6 @@ bool AttrBuilder::operator==(const AttrBuilder &B) {
return Alignment == B.Alignment && StackAlignment == B.StackAlignment;
}
-void AttrBuilder::removeFunctionOnlyAttrs() {
- removeAttribute(Attribute::NoReturn)
- .removeAttribute(Attribute::NoUnwind)
- .removeAttribute(Attribute::ReadNone)
- .removeAttribute(Attribute::ReadOnly)
- .removeAttribute(Attribute::NoInline)
- .removeAttribute(Attribute::AlwaysInline)
- .removeAttribute(Attribute::OptimizeForSize)
- .removeAttribute(Attribute::StackProtect)
- .removeAttribute(Attribute::StackProtectReq)
- .removeAttribute(Attribute::StackProtectStrong)
- .removeAttribute(Attribute::NoRedZone)
- .removeAttribute(Attribute::NoImplicitFloat)
- .removeAttribute(Attribute::Naked)
- .removeAttribute(Attribute::InlineHint)
- .removeAttribute(Attribute::StackAlignment)
- .removeAttribute(Attribute::UWTable)
- .removeAttribute(Attribute::NonLazyBind)
- .removeAttribute(Attribute::ReturnsTwice)
- .removeAttribute(Attribute::SanitizeAddress)
- .removeAttribute(Attribute::SanitizeThread)
- .removeAttribute(Attribute::SanitizeMemory)
- .removeAttribute(Attribute::MinSize)
- .removeAttribute(Attribute::NoDuplicate)
- .removeAttribute(Attribute::NoBuiltin);
-}
-
AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
// FIXME: Remove this in 4.0.
if (!Val) return *this;
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 8bfbb322cf4..ec01edfb9aa 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -301,9 +301,12 @@ namespace {
bool VerifyIntrinsicType(Type *Ty,
ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type*> &ArgTys);
- void VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
+ bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
+ void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
+ bool isFunction, const Value *V);
+ void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
bool isReturnValue, const Value *V);
- void VerifyFunctionAttrs(FunctionType *FT, const AttributeSet &Attrs,
+ void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
const Value *V);
void WriteValue(const Value *V) {
@@ -626,37 +629,66 @@ void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs,
}
}
+void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
+ bool isFunction, const Value* V) {
+ unsigned Slot = ~0U;
+ for (unsigned I = 0, E = Attrs.getNumSlots(); I != E; ++I)
+ if (Attrs.getSlotIndex(I) == Idx) {
+ Slot = I;
+ break;
+ }
+
+ assert(Slot != ~0U && "Attribute set inconsistency!");
+
+ for (AttributeSet::iterator I = Attrs.begin(Slot), E = Attrs.end(Slot);
+ I != E; ++I) {
+ if (I->isStringAttribute())
+ continue;
+
+ if (I->getKindAsEnum() == Attribute::NoReturn ||
+ I->getKindAsEnum() == Attribute::NoUnwind ||
+ I->getKindAsEnum() == Attribute::ReadNone ||
+ I->getKindAsEnum() == Attribute::ReadOnly ||
+ I->getKindAsEnum() == Attribute::NoInline ||
+ I->getKindAsEnum() == Attribute::AlwaysInline ||
+ I->getKindAsEnum() == Attribute::OptimizeForSize ||
+ I->getKindAsEnum() == Attribute::StackProtect ||
+ I->getKindAsEnum() == Attribute::StackProtectReq ||
+ I->getKindAsEnum() == Attribute::StackProtectStrong ||
+ I->getKindAsEnum() == Attribute::NoRedZone ||
+ I->getKindAsEnum() == Attribute::NoImplicitFloat ||
+ I->getKindAsEnum() == Attribute::Naked ||
+ I->getKindAsEnum() == Attribute::InlineHint ||
+ I->getKindAsEnum() == Attribute::StackAlignment ||
+ I->getKindAsEnum() == Attribute::UWTable ||
+ I->getKindAsEnum() == Attribute::NonLazyBind ||
+ I->getKindAsEnum() == Attribute::ReturnsTwice ||
+ I->getKindAsEnum() == Attribute::SanitizeAddress ||
+ I->getKindAsEnum() == Attribute::SanitizeThread ||
+ I->getKindAsEnum() == Attribute::SanitizeMemory ||
+ I->getKindAsEnum() == Attribute::MinSize ||
+ I->getKindAsEnum() == Attribute::NoDuplicate ||
+ I->getKindAsEnum() == Attribute::NoBuiltin) {
+ if (!isFunction)
+ CheckFailed("Attribute '" + I->getKindAsString() +
+ "' only applies to functions!", V);
+ return;
+ } else if (isFunction) {
+ CheckFailed("Attribute '" + I->getKindAsString() +
+ "' does not apply to functions!", V);
+ return;
+ }
+ }
+}
+
// VerifyParameterAttrs - Check the given attributes for an argument or return
// value of the specified type. The value V is printed in error messages.
-void Verifier::VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
+void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
bool isReturnValue, const Value *V) {
if (!Attrs.hasAttributes(Idx))
return;
- Assert1(!Attrs.hasAttribute(Idx, Attribute::NoReturn) &&
- !Attrs.hasAttribute(Idx, Attribute::NoUnwind) &&
- !Attrs.hasAttribute(Idx, Attribute::ReadNone) &&
- !Attrs.hasAttribute(Idx, Attribute::ReadOnly) &&
- !Attrs.hasAttribute(Idx, Attribute::NoInline) &&
- !Attrs.hasAttribute(Idx, Attribute::AlwaysInline) &&
- !Attrs.hasAttribute(Idx, Attribute::OptimizeForSize) &&
- !Attrs.hasAttribute(Idx, Attribute::StackProtect) &&
- !Attrs.hasAttribute(Idx, Attribute::StackProtectReq) &&
- !Attrs.hasAttribute(Idx, Attribute::NoRedZone) &&
- !Attrs.hasAttribute(Idx, Attribute::NoImplicitFloat) &&
- !Attrs.hasAttribute(Idx, Attribute::Naked) &&
- !Attrs.hasAttribute(Idx, Attribute::InlineHint) &&
- !Attrs.hasAttribute(Idx, Attribute::StackAlignment) &&
- !Attrs.hasAttribute(Idx, Attribute::UWTable) &&
- !Attrs.hasAttribute(Idx, Attribute::NonLazyBind) &&
- !Attrs.hasAttribute(Idx, Attribute::ReturnsTwice) &&
- !Attrs.hasAttribute(Idx, Attribute::SanitizeAddress) &&
- !Attrs.hasAttribute(Idx, Attribute::SanitizeThread) &&
- !Attrs.hasAttribute(Idx, Attribute::SanitizeMemory) &&
- !Attrs.hasAttribute(Idx, Attribute::MinSize) &&
- !Attrs.hasAttribute(Idx, Attribute::NoBuiltin),
- "Some attributes in '" + Attrs.getAsString(Idx) +
- "' only apply to functions!", V);
+ VerifyAttributeTypes(Attrs, Idx, false, V);
if (isReturnValue)
Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) &&
@@ -712,8 +744,7 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, uint64_t Idx, Type *Ty,
// VerifyFunctionAttrs - Check parameter attributes against a function type.
// The value V is printed in error messages.
-void Verifier::VerifyFunctionAttrs(FunctionType *FT,
- const AttributeSet &Attrs,
+void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
const Value *V) {
if (Attrs.isEmpty())
return;
@@ -721,72 +752,31 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
bool SawNest = false;
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
- unsigned Index = Attrs.getSlotIndex(i);
+ unsigned Idx = Attrs.getSlotIndex(i);
Type *Ty;
- if (Index == 0)
+ if (Idx == 0)
Ty = FT->getReturnType();
- else if (Index-1 < FT->getNumParams())
- Ty = FT->getParamType(Index-1);
+ else if (Idx-1 < FT->getNumParams())
+ Ty = FT->getParamType(Idx-1);
else
break; // VarArgs attributes, verified elsewhere.
- VerifyParameterAttrs(Attrs, Index, Ty, Index == 0, V);
+ VerifyParameterAttrs(Attrs, Idx, Ty, Idx == 0, V);
if (Attrs.hasAttribute(i, Attribute::Nest)) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
- if (Attrs.hasAttribute(Index, Attribute::StructRet))
- Assert1(Index == 1, "Attribute sret is not on first parameter!", V);
+ if (Attrs.hasAttribute(Idx, Attribute::StructRet))
+ Assert1(Idx == 1, "Attribute sret is not on first parameter!", V);
}
if (!Attrs.hasAttributes(AttributeSet::FunctionIndex))
return;
- AttrBuilder NotFn(Attrs, AttributeSet::FunctionIndex);
- NotFn.removeFunctionOnlyAttrs();
- Assert1(NotFn.empty(), "Attributes '" +
- AttributeSet::get(V->getContext(),
- AttributeSet::FunctionIndex,
- NotFn).getAsString(AttributeSet::FunctionIndex) +
- "' do not apply to the function!", V);
-
- // Check for mutually incompatible attributes.
- Assert1(!((Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ByVal) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::Nest)) ||
- (Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ByVal) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::StructRet)) ||
- (Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::Nest) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::StructRet))),
- "Attributes 'byval, nest, and sret' are incompatible!", V);
-
- Assert1(!((Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ByVal) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::Nest)) ||
- (Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ByVal) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::InReg)) ||
- (Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::Nest) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::InReg))),
- "Attributes 'byval, nest, and inreg' are incompatible!", V);
-
- Assert1(!(Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::ZExt) &&
- Attrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::SExt)),
- "Attributes 'zeroext and signext' are incompatible!", V);
+ VerifyAttributeTypes(Attrs, AttributeSet::FunctionIndex, true, V);
Assert1(!(Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::ReadNone) &&
@@ -801,7 +791,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
"Attributes 'noinline and alwaysinline' are incompatible!", V);
}
-static bool VerifyAttributeCount(const AttributeSet &Attrs, unsigned Params) {
+bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) {
if (Attrs.getNumSlots() == 0)
return true;
@@ -837,7 +827,7 @@ void Verifier::visitFunction(Function &F) {
Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(),
"Invalid struct return type!", &F);
- const AttributeSet &Attrs = F.getAttributes();
+ AttributeSet Attrs = F.getAttributes();
Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()),
"Attribute after last parameter!", &F);
@@ -1350,7 +1340,7 @@ void Verifier::VerifyCallSite(CallSite CS) {
"Call parameter type does not match function signature!",
CS.getArgument(i), FTy->getParamType(i), I);
- const AttributeSet &Attrs = CS.getAttributes();
+ AttributeSet Attrs = CS.getAttributes();
Assert1(VerifyAttributeCount(Attrs, CS.arg_size()),
"Attribute after last parameter!", I);