diff options
author | Reid Kleckner <rnk@google.com> | 2017-04-10 23:31:05 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-04-10 23:31:05 +0000 |
commit | 7dde8e89fc9e76729f9420314597395d1b47431b (patch) | |
tree | 0fc0be07886670cd80d4fe9429225bb8ce449d38 /lib/AsmParser | |
parent | ed488fa93ddf897c033554c46d37d66258f37bbe (diff) |
Reland "[IR] Make AttributeSetNode public, avoid temporary AttributeList copies"
This re-lands r299875.
I introduced a bug in Clang code responsible for replacing K&R, no
prototype declarations with a real function definition with a prototype.
The bug was here:
// Collect any return attributes from the call.
- if (oldAttrs.hasAttributes(llvm::AttributeList::ReturnIndex))
- newAttrs.push_back(llvm::AttributeList::get(newFn->getContext(),
- oldAttrs.getRetAttributes()));
+ newAttrs.push_back(oldAttrs.getRetAttributes());
Previously getRetAttributes() carried AttributeList::ReturnIndex in its
AttributeList. Now that we return the AttributeSetNode* directly, it no
longer carries that index, and we call this overload with a single node:
AttributeList::get(LLVMContext&, ArrayRef<AttributeSetNode*>)
That aborted with an assertion on x86_32 targets. I added an explicit
triple to the test and added CHECKs to help find issues like this in the
future sooner.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299899 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 88 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 8 |
2 files changed, 34 insertions, 62 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 941ee347a78..ffe620348fb 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/IR/Argument.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" @@ -131,9 +132,8 @@ bool LLParser::ValidateEndOfModule() { if (Function *Fn = dyn_cast<Function>(V)) { AttributeList AS = Fn->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); @@ -150,9 +150,8 @@ bool LLParser::ValidateEndOfModule() { Fn->setAttributes(AS); } else if (CallInst *CI = dyn_cast<CallInst>(V)) { AttributeList AS = CI->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); AS = AS.addAttributes( Context, AttributeList::FunctionIndex, @@ -160,9 +159,8 @@ bool LLParser::ValidateEndOfModule() { CI->setAttributes(AS); } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) { AttributeList AS = II->getAttributes(); - AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex); - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex, - AS.getFnAttributes()); + AttrBuilder FnAttrs(AS.getFnAttributes()); + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex); FnAttrs.merge(B); AS = AS.addAttributes( Context, AttributeList::FunctionIndex, @@ -2123,7 +2121,6 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; - unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -2158,7 +2155,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, return true; } ArgList.push_back(ParamInfo( - ArgLoc, V, AttributeList::get(V->getContext(), AttrIndex++, ArgAttrs))); + ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs))); } if (IsMustTailCall && InVarArgsFunc) @@ -2263,9 +2260,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - unsigned AttrIndex = 1; - ArgList.emplace_back(TypeLoc, ArgTy, AttributeList::get(ArgTy->getContext(), - AttrIndex++, Attrs), + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSetNode::get(ArgTy->getContext(), Attrs), std::move(Name)); while (EatIfPresent(lltok::comma)) { @@ -2292,10 +2288,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.emplace_back( - TypeLoc, ArgTy, - AttributeList::get(ArgTy->getContext(), AttrIndex++, Attrs), - std::move(Name)); + ArgList.emplace_back(TypeLoc, ArgTy, + AttributeSetNode::get(ArgTy->getContext(), Attrs), + std::move(Name)); } } @@ -2319,7 +2314,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { if (!ArgList[i].Name.empty()) return Error(ArgList[i].Loc, "argument name invalid in function type"); - if (ArgList[i].Attrs.hasAttributes(i + 1)) + if (ArgList[i].Attrs) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -4768,23 +4763,16 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Okay, if we got here, the function is syntactically valid. Convert types // and do semantic checks. std::vector<Type*> ParamTypeList; - SmallVector<AttributeList, 8> Attrs; + SmallVector<AttributeSetNode *, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } - if (FuncAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get( - RetType->getContext(), AttributeList::FunctionIndex, FuncAttrs)); + Attrs.push_back(AttributeSetNode::get(Context, FuncAttrs)); AttributeList PAL = AttributeList::get(Context, Attrs); @@ -5396,10 +5384,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return true; // Set up the Attribute for the function. - SmallVector<AttributeList, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + SmallVector<AttributeSetNode *, 8> Attrs; + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); SmallVector<Value*, 8> Args; @@ -5419,22 +5405,16 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "invoke instructions may not have an alignment"); + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "invoke instructions may not have an alignment"); - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::FunctionIndex, FnAttrs)); - } + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs)); // Finish off the Attribute and check them AttributeList PAL = AttributeList::get(Context, Attrs); @@ -5998,10 +5978,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return true; // Set up the Attribute for the function. - SmallVector<AttributeList, 8> Attrs; - if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::ReturnIndex, RetAttrs)); + SmallVector<AttributeSetNode *, 8> Attrs; + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs)); SmallVector<Value*, 8> Args; @@ -6021,22 +5999,16 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes(i + 1)) { - AttrBuilder B(ArgList[i].Attrs, i + 1); - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B)); - } + Attrs.push_back(ArgList[i].Attrs); } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); - if (FnAttrs.hasAttributes()) { - if (FnAttrs.hasAlignmentAttr()) - return Error(CallLoc, "call instructions may not have an alignment"); + if (FnAttrs.hasAlignmentAttr()) + return Error(CallLoc, "call instructions may not have an alignment"); - Attrs.push_back(AttributeList::get(RetType->getContext(), - AttributeList::FunctionIndex, FnAttrs)); - } + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs)); // Finish off the Attribute and check them AttributeList PAL = AttributeList::get(Context, Attrs); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 5293bda1b70..2b693331548 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -397,8 +397,8 @@ namespace llvm { struct ParamInfo { LocTy Loc; Value *V; - AttributeList Attrs; - ParamInfo(LocTy loc, Value *v, AttributeList attrs) + AttributeSetNode *Attrs; + ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs) : Loc(loc), V(v), Attrs(attrs) {} }; bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, @@ -450,9 +450,9 @@ namespace llvm { struct ArgInfo { LocTy Loc; Type *Ty; - AttributeList Attrs; + AttributeSetNode *Attrs; std::string Name; - ArgInfo(LocTy L, Type *ty, AttributeList Attr, const std::string &N) + ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const std::string &N) : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} }; bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg); |