Skip to content

Commit 2b7dcba

Browse files
author
Gabor Horvath
committed
[cxx-interop] Do not generate Span wrappers that depend on a reference type
We currently do not have sound enforcement of exclusivity in those cases regardless of mutability. Let's not generate these methods for now until we figure out how to make them safer. rdar://163068618
1 parent 870acb5 commit 2b7dcba

File tree

2 files changed

+6
-29
lines changed

2 files changed

+6
-29
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4199,20 +4199,6 @@ namespace {
41994199
return false;
42004200
}
42014201

4202-
static bool canTypeMutateBuffer(clang::QualType ty) {
4203-
// FIXME: better way to detect if a type can mutate the underlying buffer.
4204-
if (const auto *rd = ty->getAsRecordDecl()) {
4205-
if (rd->isInStdNamespace() && rd->getName() == "span")
4206-
return !cast<clang::ClassTemplateSpecializationDecl>(rd)
4207-
->getTemplateArgs()
4208-
.get(0)
4209-
.getAsType()
4210-
.isConstQualified();
4211-
}
4212-
// Conservatively assume most types can mutate the underlying buffer.
4213-
return true;
4214-
}
4215-
42164202
void addLifetimeDependencies(const clang::FunctionDecl *decl,
42174203
AbstractFunctionDecl *result) {
42184204
if (decl->getTemplatedKind() == clang::FunctionDecl::TK_FunctionTemplate)
@@ -4267,7 +4253,6 @@ namespace {
42674253
}
42684254

42694255
auto retType = decl->getReturnType();
4270-
bool retMayMutateBuffer = canTypeMutateBuffer(retType);
42714256
auto warnForEscapableReturnType = [&] {
42724257
if (isEscapableAnnotatedType(retType.getTypePtr())) {
42734258
Impl.addImportDiagnostic(
@@ -4286,7 +4271,7 @@ namespace {
42864271
auto processLifetimeBound = [&](unsigned idx, clang::QualType ty,
42874272
bool forSelf = false) {
42884273
warnForEscapableReturnType();
4289-
if (retMayMutateBuffer && importedAsClass(ty, forSelf))
4274+
if (importedAsClass(ty, forSelf))
42904275
hasSkippedLifetimeAnnotation = true;
42914276
paramHasAnnotation[idx] = true;
42924277
if (isEscapable(ty))
@@ -9583,18 +9568,15 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
95839568
SIW_DBG(" Found bounds info '" << clang::QualType(CAT, 0) << "' on return value\n");
95849569
attachMacro = true;
95859570
}
9586-
auto requiresExclusiveClassDependency = [](ParamDecl *fromParam,
9587-
clang::QualType toType) {
9588-
return fromParam->getInterfaceType()->isAnyClassReferenceType() &&
9589-
SwiftDeclConverter::canTypeMutateBuffer(toType);
9571+
auto dependsOnClass = [](ParamDecl *fromParam) {
9572+
return fromParam->getInterfaceType()->isAnyClassReferenceType();
95909573
};
95919574
bool returnHasLifetimeInfo = false;
95929575
if (SwiftDeclConverter::getImplicitObjectParamAnnotation<
95939576
clang::LifetimeBoundAttr>(ClangDecl)) {
95949577
SIW_DBG(" Found lifetimebound attribute on implicit 'this'\n");
9595-
if (!requiresExclusiveClassDependency(
9596-
MappedDecl->getImplicitSelfDecl(/*createIfNeeded*/ true),
9597-
ClangDecl->getReturnType())) {
9578+
if (!dependsOnClass(
9579+
MappedDecl->getImplicitSelfDecl(/*createIfNeeded*/ true))) {
95989580
printer.printLifetimeboundReturn(SwiftifyInfoPrinter::SELF_PARAM_INDEX,
95999581
true);
96009582
returnHasLifetimeInfo = true;
@@ -9655,8 +9637,7 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
96559637
if (clangParam->hasAttr<clang::LifetimeBoundAttr>()) {
96569638
SIW_DBG(" Found lifetimebound attribute on parameter '"
96579639
<< *clangParam << "'\n");
9658-
if (!requiresExclusiveClassDependency(swiftParam,
9659-
ClangDecl->getReturnType())) {
9640+
if (!dependsOnClass(swiftParam)) {
96609641
// If this parameter has bounds info we will tranform it into a Span,
96619642
// so then it will no longer be Escapable.
96629643
bool willBeEscapable =

test/Interop/Cxx/stdlib/std-span-interface.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ import CxxStdlib
4040

4141
// CHECK: class DependsOnSelfFRT {
4242
// CHECK-NEXT: init()
43-
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
44-
// CHECK-NEXT: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
45-
// CHECK-NEXT: @_lifetime(borrow self)
46-
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public borrowing func get() -> Span<CInt>
4743
// CHECK-NEXT: borrowing func get() -> ConstSpanOfInt
4844
// CHECK-NEXT: borrowing func {{(__)?}}getMutable{{(Unsafe)?}}() -> SpanOfInt
4945
// CHECK-NEXT: var v: std.{{.*}}vector<CInt, std.{{.*}}allocator<CInt>>

0 commit comments

Comments
 (0)