From: John McCall Date: Wed, 3 Aug 2011 00:43:55 +0000 (+0000) Subject: When rewriting a call to a K&R function to lead to a well-prototyped X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=40f9c302f23a35611cd354f40b22b37f2c554a40;p=clang When rewriting a call to a K&R function to lead to a well-prototyped function, be sure to drop parameter attributes when dropping their associated arguments. Patch by Aaron Landwehr! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136753 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 12f09b1c65..6651282384 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1407,6 +1407,17 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, if (CI->getType() != NewRetTy && !CI->use_empty()) continue; + // Get the attribute list. + llvm::SmallVector AttrVec; + llvm::AttrListPtr AttrList = CI->getAttributes(); + + // Get any return attributes. + llvm::Attributes RAttrs = AttrList.getRetAttributes(); + + // Add the return attributes. + if (RAttrs) + AttrVec.push_back(llvm::AttributeWithIndex::get(0, RAttrs)); + // If the function was passed too few arguments, don't transform. If extra // arguments were passed, we silently drop them. If any of the types // mismatch, we don't transform. @@ -1419,10 +1430,17 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, DontTransform = true; break; } + + // Add any parameter attributes. + if (llvm::Attributes PAttrs = AttrList.getParamAttributes(ArgNo + 1)) + AttrVec.push_back(llvm::AttributeWithIndex::get(ArgNo + 1, PAttrs)); } if (DontTransform) continue; + if (llvm::Attributes FnAttrs = AttrList.getFnAttributes()) + AttrVec.push_back(llvm::AttributeWithIndex::get(~0, FnAttrs)); + // Okay, we can transform this. Create the new call instruction and copy // over the required information. ArgList.append(CS.arg_begin(), CS.arg_begin() + ArgNo); @@ -1430,7 +1448,8 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, ArgList.clear(); if (!NewCall->getType()->isVoidTy()) NewCall->takeName(CI); - NewCall->setAttributes(CI->getAttributes()); + NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec.begin(), + AttrVec.end())); NewCall->setCallingConv(CI->getCallingConv()); // Finally, remove the old call, replacing any uses with the new one. diff --git a/test/CodeGen/kr-call.c b/test/CodeGen/kr-call.c new file mode 100644 index 0000000000..97068bce0c --- /dev/null +++ b/test/CodeGen/kr-call.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple s390x-unknown-linux -emit-llvm -o - %s | FileCheck %s + +// Test that we don't crash. The s390x-unknown-linux target happens +// to need to set a sext argument attribute on this call, and we need +// to make sure that rewriting it correctly drops that attribute when +// also dropping the spurious argument. +void test0_helper(); +void test0() { + // CHECK: call void @test0_helper() + test0_helper(1); +} +void test0_helper() {} +