Skip to content

Commit 008a2a1

Browse files
committed
[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
1 parent 79cdadf commit 008a2a1

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
266266
llvm::AttrBuilder b(IGM.getLLVMContext());
267267
// Value parameter pointers can't alias or be captured.
268268
b.addAttribute(llvm::Attribute::NoAlias);
269-
b.addAttribute(llvm::Attribute::NoCapture);
269+
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
270+
b.addAttribute(llvm::Attribute::NoCapture);
270271
// The parameter must reference dereferenceable memory of the type.
271272
addDereferenceableAttributeToBuilder(IGM, b, ti);
272273

@@ -278,9 +279,11 @@ static void addPackParameterAttributes(IRGenModule &IGM,
278279
llvm::AttributeList &attrs,
279280
unsigned argIndex) {
280281
llvm::AttrBuilder b(IGM.getLLVMContext());
281-
// Pack parameter pointers can't alias or be captured.
282+
// Pack parameter pointers can't alias.
283+
// Note: they are not marked `nocapture` as one
284+
// pack parameter could be a value type (e.g. a C++ type)
285+
// that captures its own pointer in itself.
282286
b.addAttribute(llvm::Attribute::NoAlias);
283-
b.addAttribute(llvm::Attribute::NoCapture);
284287
// TODO: we could mark this dereferenceable when the pack has fixed
285288
// components.
286289
// TODO: add an alignment attribute
@@ -302,7 +305,8 @@ static void addInoutParameterAttributes(IRGenModule &IGM, SILType paramSILType,
302305
b.addAttribute(llvm::Attribute::NoAlias);
303306
}
304307
// Aliasing inouts can't be captured without doing unsafe stuff.
305-
b.addAttribute(llvm::Attribute::NoCapture);
308+
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
309+
b.addAttribute(llvm::Attribute::NoCapture);
306310
// The inout must reference dereferenceable memory of the type.
307311
addDereferenceableAttributeToBuilder(IGM, b, ti);
308312

@@ -341,10 +345,12 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM,
341345
static void addIndirectResultAttributes(IRGenModule &IGM,
342346
llvm::AttributeList &attrs,
343347
unsigned paramIndex, bool allowSRet,
344-
llvm::Type *storageType) {
348+
llvm::Type *storageType,
349+
const TypeInfo &typeInfo) {
345350
llvm::AttrBuilder b(IGM.getLLVMContext());
346351
b.addAttribute(llvm::Attribute::NoAlias);
347-
b.addAttribute(llvm::Attribute::NoCapture);
352+
if (typeInfo.isBitwiseTakable(ResilienceExpansion::Maximal))
353+
b.addAttribute(llvm::Attribute::NoCapture);
348354
if (allowSRet) {
349355
assert(storageType);
350356
b.addStructRetAttr(storageType);
@@ -509,7 +515,7 @@ llvm::Type *SignatureExpansion::addIndirectResult() {
509515
const TypeInfo &resultTI = IGM.getTypeInfo(resultType);
510516
auto storageTy = resultTI.getStorageType();
511517
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet(),
512-
storageTy);
518+
storageTy, resultTI);
513519
addPointerParameter(storageTy);
514520
return IGM.VoidTy;
515521
}
@@ -568,11 +574,12 @@ void SignatureExpansion::expandIndirectResults() {
568574
auto useSRet = claimSRet();
569575
// We need to use opaque types or non fixed size storage types because llvm
570576
// does type based analysis based on the type of sret arguments.
571-
if (useSRet && !isa<FixedTypeInfo>(IGM.getTypeInfo(indirectResultType))) {
577+
const TypeInfo &typeInfo = IGM.getTypeInfo(indirectResultType);
578+
if (useSRet && !isa<FixedTypeInfo>(typeInfo)) {
572579
storageTy = IGM.OpaqueTy;
573580
}
574581
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), useSRet,
575-
storageTy);
582+
storageTy, typeInfo);
576583
addPointerParameter(storageTy);
577584
}
578585
}
@@ -1459,7 +1466,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
14591466
param, IGM.getMaximalTypeExpansionContext());
14601467
auto &paramTI = cast<FixedTypeInfo>(IGM.getTypeInfo(paramTy));
14611468
addIndirectResultAttributes(IGM, Attrs, getCurParamIndex(), claimSRet(),
1462-
paramTI.getStorageType());
1469+
paramTI.getStorageType(), paramTI);
14631470
break;
14641471
}
14651472
}

0 commit comments

Comments
 (0)