Skip to content

Commit 3e89932

Browse files
committed
[interop][SwiftToCxx] do not expose Swift APIs with shared FRTs as their ownership is not yet managed at the language boundary
1 parent 89abd76 commit 3e89932

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/ClangImporter/ClangImporter.h"
3131
#include "swift/IRGen/IRABIDetailsProvider.h"
3232
#include "clang/AST/ASTContext.h"
33+
#include "clang/AST/Attr.h"
3334
#include "clang/AST/DeclObjC.h"
3435
#include "llvm/ADT/STLExtras.h"
3536

@@ -281,6 +282,25 @@ class CFunctionSignatureTypePrinter
281282
os << " __strong";
282283
printInoutTypeModifier();
283284
}
285+
if (isa<clang::CXXRecordDecl>(cd->getClangDecl())) {
286+
if (std::find_if(
287+
cd->getClangDecl()->getAttrs().begin(),
288+
cd->getClangDecl()->getAttrs().end(), [](clang::Attr *attr) {
289+
if (auto *sa = dyn_cast<clang::SwiftAttrAttr>(attr)) {
290+
llvm::StringRef value = sa->getAttribute();
291+
if ((value.startswith("retain:") ||
292+
value.startswith("release:")) &&
293+
!value.endswith(":immortal"))
294+
return true;
295+
}
296+
return false;
297+
}) != cd->getClangDecl()->getAttrs().end()) {
298+
// This is a shared FRT. Do not bridge it back to
299+
// C++ as its ownership is not managed automatically
300+
// in C++ yet.
301+
return ClangRepresentation::unsupported;
302+
}
303+
}
284304
// FIXME: Mark that this is only ObjC representable.
285305
return ClangRepresentation::representable;
286306
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -typecheck %t/use-cxx-types.swift -typecheck -module-name UseCxxTy -emit-clang-header-path %t/UseCxxTy.h -I %t -enable-experimental-cxx-interop -clang-header-expose-decls=all-public -disable-availability-checking
5+
6+
// RUN: %FileCheck %s < %t/UseCxxTy.h
7+
8+
//--- header.h
9+
10+
class SharedFRT {
11+
public:
12+
int x;
13+
} __attribute__((swift_attr("import_reference")))
14+
__attribute__((swift_attr("retain:retainShared")))
15+
__attribute__((swift_attr("release:releaseShared")));
16+
17+
inline void retainShared(SharedFRT *r) { }
18+
inline void releaseShared(SharedFRT *r) { }
19+
20+
//--- module.modulemap
21+
module CxxTest {
22+
header "header.h"
23+
requires cplusplus
24+
}
25+
26+
//--- use-cxx-types.swift
27+
import CxxTest
28+
29+
public func consumeSharedFRT(_ x: consuming SharedFRT) {}
30+
public func takeSharedFRT(_ x: SharedFRT) {}
31+
32+
// CHECK: Unavailable in C++: Swift global function 'consumeSharedFRT(_:)'.
33+
34+
// CHECK: Unavailable in C++: Swift global function 'takeSharedFRT(_:)'.

0 commit comments

Comments
 (0)