Skip to content

Commit 23798a9

Browse files
committedMar 26, 2014
CloneFunction: Clone all attributes, including the CC
Summary: Tested with a unit test because we don't appear to have any transforms that use this other than ASan, I think. Fixes PR17935. Reviewers: nicholas CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D3194 llvm-svn: 204866
1 parent b9aea93 commit 23798a9

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed
 

‎llvm/lib/Transforms/Utils/CloneFunction.cpp

+16-14
Original file line numberDiff line numberDiff line change
@@ -89,26 +89,28 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
8989
assert(VMap.count(I) && "No mapping from source argument specified!");
9090
#endif
9191

92+
// Copy all attributes other than those stored in the AttributeSet. We need
93+
// to remap the parameter indices of the AttributeSet.
94+
AttributeSet NewAttrs = NewFunc->getAttributes();
95+
NewFunc->copyAttributesFrom(OldFunc);
96+
NewFunc->setAttributes(NewAttrs);
97+
9298
AttributeSet OldAttrs = OldFunc->getAttributes();
9399
// Clone any argument attributes that are present in the VMap.
94-
for (Function::const_arg_iterator I = OldFunc->arg_begin(),
95-
E = OldFunc->arg_end();
96-
I != E; ++I)
97-
if (Argument *Anew = dyn_cast<Argument>(VMap[I])) {
100+
for (const Argument &OldArg : OldFunc->args())
101+
if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
98102
AttributeSet attrs =
99-
OldAttrs.getParamAttributes(I->getArgNo() + 1);
103+
OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
100104
if (attrs.getNumSlots() > 0)
101-
Anew->addAttr(attrs);
105+
NewArg->addAttr(attrs);
102106
}
103107

104-
NewFunc->setAttributes(NewFunc->getAttributes()
105-
.addAttributes(NewFunc->getContext(),
106-
AttributeSet::ReturnIndex,
107-
OldAttrs.getRetAttributes()));
108-
NewFunc->setAttributes(NewFunc->getAttributes()
109-
.addAttributes(NewFunc->getContext(),
110-
AttributeSet::FunctionIndex,
111-
OldAttrs.getFnAttributes()));
108+
NewFunc->setAttributes(
109+
NewFunc->getAttributes()
110+
.addAttributes(NewFunc->getContext(), AttributeSet::ReturnIndex,
111+
OldAttrs.getRetAttributes())
112+
.addAttributes(NewFunc->getContext(), AttributeSet::FunctionIndex,
113+
OldAttrs.getFnAttributes()));
112114

113115
// Loop over all of the basic blocks in the function, cloning them as
114116
// appropriate. Note that we save BE this way in order to handle cloning of

‎llvm/unittests/Transforms/Utils/Cloning.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,29 @@ TEST_F(CloneInstruction, Attributes) {
180180
delete F2;
181181
}
182182

183+
TEST_F(CloneInstruction, CallingConvention) {
184+
Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
185+
FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
186+
187+
Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
188+
F1->setCallingConv(CallingConv::Cold);
189+
BasicBlock *BB = BasicBlock::Create(context, "", F1);
190+
IRBuilder<> Builder(BB);
191+
Builder.CreateRetVoid();
192+
193+
Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
194+
195+
SmallVector<ReturnInst*, 4> Returns;
196+
ValueToValueMapTy VMap;
197+
VMap[F1->arg_begin()] = F2->arg_begin();
198+
199+
CloneFunctionInto(F2, F1, VMap, false, Returns);
200+
EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
201+
202+
delete F1;
203+
delete F2;
204+
}
205+
183206
class CloneFunc : public ::testing::Test {
184207
protected:
185208
virtual void SetUp() {

0 commit comments

Comments
 (0)
Please sign in to comment.