mirror of https://github.com/microsoft/clang.git
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/cfe/trunk@299899 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0d684b104b
commit
c84d5c0f2c
|
@ -2935,13 +2935,11 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
|
|||
continue;
|
||||
|
||||
// Get the call site's attribute list.
|
||||
SmallVector<llvm::AttributeList, 8> newAttrs;
|
||||
SmallVector<llvm::AttributeSetNode *, 8> newAttrs;
|
||||
llvm::AttributeList oldAttrs = callSite.getAttributes();
|
||||
|
||||
// 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());
|
||||
|
||||
// If the function was passed too few arguments, don't transform.
|
||||
unsigned newNumArgs = newFn->arg_size();
|
||||
|
@ -2959,16 +2957,12 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
|
|||
}
|
||||
|
||||
// Add any parameter attributes.
|
||||
if (oldAttrs.hasAttributes(argNo + 1))
|
||||
newAttrs.push_back(llvm::AttributeList::get(
|
||||
newFn->getContext(), oldAttrs.getParamAttributes(argNo + 1)));
|
||||
newAttrs.push_back(oldAttrs.getParamAttributes(argNo + 1));
|
||||
}
|
||||
if (dontTransform)
|
||||
continue;
|
||||
|
||||
if (oldAttrs.hasAttributes(llvm::AttributeList::FunctionIndex))
|
||||
newAttrs.push_back(llvm::AttributeList::get(newFn->getContext(),
|
||||
oldAttrs.getFnAttributes()));
|
||||
newAttrs.push_back(oldAttrs.getFnAttributes());
|
||||
|
||||
// Okay, we can transform this. Create the new call instruction and copy
|
||||
// over the required information.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Test returning a single element aggregate value containing a double.
|
||||
// RUN: %clang_cc1 -triple i686-linux %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_32
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o -
|
||||
|
||||
struct X {
|
||||
double D;
|
||||
};
|
||||
|
||||
struct Y {
|
||||
struct X x;
|
||||
struct Y {
|
||||
struct X x;
|
||||
};
|
||||
|
||||
struct Y bar();
|
||||
|
@ -21,3 +22,9 @@ struct Y bar() {
|
|||
return a;
|
||||
}
|
||||
|
||||
|
||||
// X86_32: define void @foo(%struct.Y* %P)
|
||||
// X86_32: call void @bar(%struct.Y* sret %{{[^),]*}})
|
||||
|
||||
// X86_32: define void @bar(%struct.Y* noalias sret %{{[^,)]*}})
|
||||
// X86_32: ret void
|
||||
|
|
Loading…
Reference in New Issue