mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[IRGen][interop] do not add 'nocapture' to not bitwise takable types
The use of 'nocapture' for parameters and return values is incorrect for C++ types, as they can actually capture a pointer into its own value (e.g. std::string in libstdc++) rdar://115062687
This commit is contained in:
@@ -266,7 +266,10 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
|
||||
llvm::AttrBuilder b(IGM.getLLVMContext());
|
||||
// Value parameter pointers can't alias or be captured.
|
||||
b.addAttribute(llvm::Attribute::NoAlias);
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// Bitwise takable value types are guaranteed not to capture
|
||||
// a pointer into itself.
|
||||
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// The parameter must reference dereferenceable memory of the type.
|
||||
addDereferenceableAttributeToBuilder(IGM, b, ti);
|
||||
|
||||
@@ -278,9 +281,11 @@ static void addPackParameterAttributes(IRGenModule &IGM,
|
||||
llvm::AttributeList &attrs,
|
||||
unsigned argIndex) {
|
||||
llvm::AttrBuilder b(IGM.getLLVMContext());
|
||||
// Pack parameter pointers can't alias or be captured.
|
||||
// Pack parameter pointers can't alias.
|
||||
// Note: they are not marked `nocapture` as one
|
||||
// pack parameter could be a value type (e.g. a C++ type)
|
||||
// that captures its own pointer in itself.
|
||||
b.addAttribute(llvm::Attribute::NoAlias);
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// TODO: we could mark this dereferenceable when the pack has fixed
|
||||
// components.
|
||||
// TODO: add an alignment attribute
|
||||
@@ -301,8 +306,10 @@ static void addInoutParameterAttributes(IRGenModule &IGM, SILType paramSILType,
|
||||
// attribute if it's a pointer being passed inout.
|
||||
b.addAttribute(llvm::Attribute::NoAlias);
|
||||
}
|
||||
// Aliasing inouts can't be captured without doing unsafe stuff.
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// Bitwise takable value types are guaranteed not to capture
|
||||
// a pointer into itself.
|
||||
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// The inout must reference dereferenceable memory of the type.
|
||||
addDereferenceableAttributeToBuilder(IGM, b, ti);
|
||||
|
||||
@@ -341,10 +348,14 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM,
|
||||
static void addIndirectResultAttributes(IRGenModule &IGM,
|
||||
llvm::AttributeList &attrs,
|
||||
unsigned paramIndex, bool allowSRet,
|
||||
llvm::Type *storageType) {
|
||||
llvm::Type *storageType,
|
||||
const TypeInfo &typeInfo) {
|
||||
llvm::AttrBuilder b(IGM.getLLVMContext());
|
||||
b.addAttribute(llvm::Attribute::NoAlias);
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
// Bitwise takable value types are guaranteed not to capture
|
||||
// a pointer into itself.
|
||||
if (typeInfo.isBitwiseTakable(ResilienceExpansion::Maximal))
|
||||
b.addAttribute(llvm::Attribute::NoCapture);
|
||||
if (allowSRet) {
|
||||
assert(storageType);
|
||||
b.addStructRetAttr(storageType);
|
||||
@@ -509,7 +520,7 @@ llvm::Type *SignatureExpansion::addIndirectResult() {
|
||||
const TypeInfo &resultTI = IGM.getTypeInfo(resultType);
|
||||
auto storageTy = resultTI.getStorageType();
|
||||
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet(),
|
||||
storageTy);
|
||||
storageTy, resultTI);
|
||||
addPointerParameter(storageTy);
|
||||
return IGM.VoidTy;
|
||||
}
|
||||
@@ -568,11 +579,12 @@ void SignatureExpansion::expandIndirectResults() {
|
||||
auto useSRet = claimSRet();
|
||||
// We need to use opaque types or non fixed size storage types because llvm
|
||||
// does type based analysis based on the type of sret arguments.
|
||||
if (useSRet && !isa<FixedTypeInfo>(IGM.getTypeInfo(indirectResultType))) {
|
||||
const TypeInfo &typeInfo = IGM.getTypeInfo(indirectResultType);
|
||||
if (useSRet && !isa<FixedTypeInfo>(typeInfo)) {
|
||||
storageTy = IGM.OpaqueTy;
|
||||
}
|
||||
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), useSRet,
|
||||
storageTy);
|
||||
storageTy, typeInfo);
|
||||
addPointerParameter(storageTy);
|
||||
}
|
||||
}
|
||||
@@ -1459,7 +1471,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
|
||||
param, IGM.getMaximalTypeExpansionContext());
|
||||
auto ¶mTI = cast<FixedTypeInfo>(IGM.getTypeInfo(paramTy));
|
||||
addIndirectResultAttributes(IGM, Attrs, getCurParamIndex(), claimSRet(),
|
||||
paramTI.getStorageType());
|
||||
paramTI.getStorageType(), paramTI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user