]> granicus.if.org Git - clang/commitdiff
When rewriting a call to a K&R function to lead to a well-prototyped
authorJohn McCall <rjmccall@apple.com>
Wed, 3 Aug 2011 00:43:55 +0000 (00:43 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 3 Aug 2011 00:43:55 +0000 (00:43 +0000)
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

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/kr-call.c [new file with mode: 0644]

index 12f09b1c6576b3b7c344cb4285ee0d279de7ffe1..6651282384eb2ea72a8f61307c5a6d3269293d91 100644 (file)
@@ -1407,6 +1407,17 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
     if (CI->getType() != NewRetTy && !CI->use_empty())
       continue;
 
+    // Get the attribute list.
+    llvm::SmallVector<llvm::AttributeWithIndex, 8> 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 (file)
index 0000000..97068bc
--- /dev/null
@@ -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() {}
+