diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-04-18 20:15:25 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-04-18 20:15:25 +0000 |
commit | bb1b63c48397a3bac5d00f2ac9d33cc14efd714c (patch) | |
tree | fd01da2199225cea17f87952fc4a790e8d897f41 /lib/IR | |
parent | 4b15d6ae49b407cfcf526a3f7bec7ab15fa803c0 (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/IR')
-rw-r--r-- | lib/IR/Attributes.cpp | 27 | ||||
-rw-r--r-- | lib/IR/Verifier.cpp | 152 |
2 files changed, 71 insertions, 108 deletions
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index b513f7dc84..f434b8e8c3 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 8bfbb322cf..ec01edfb9a 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); |