mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Explanation: There was an inconsistency between non-const and const FRT pointers. The former used Direct_Unowned the latter used Indirect calling convention. We want to use Direct_Unowned for both cases. The crash was the result of a calling convention mismatch between the SILFunctionType of a Swift closure and the SILFunctionType of the C++ function's formal parameter that is taking a function pointer. The compiler tried to insert a conversion between the two function types that does not exist and caused an assertion in debug compilers and miscompilation in production compilers. Issue: rdar://149398905 Risk: Low, the fix is targeted and we change to a well-tested behavior with non-const FRT pointers. Testing: Regression test added. Original PR: #81070 Reviewer: @j-hui
79 lines
1.9 KiB
C++
79 lines
1.9 KiB
C++
#ifndef __CLOSURE__
|
|
#define __CLOSURE__
|
|
|
|
struct NonTrivial {
|
|
NonTrivial() noexcept { p = new int(123); }
|
|
~NonTrivial() { delete p; }
|
|
NonTrivial(const NonTrivial &other) noexcept {
|
|
p = new int(*other.p);
|
|
}
|
|
int *p;
|
|
};
|
|
|
|
void cfunc(void (^ _Nonnull block)(NonTrivial)) noexcept {
|
|
block(NonTrivial());
|
|
}
|
|
|
|
void cfunc2(void (*_Nonnull fp)(NonTrivial)) noexcept { (*fp)(NonTrivial()); }
|
|
|
|
NonTrivial cfunc3(NonTrivial, int, NonTrivial);
|
|
|
|
#if __OBJC__
|
|
struct ARCStrong {
|
|
id a;
|
|
};
|
|
|
|
void cfuncARCStrong(void (*_Nonnull)(ARCStrong)) noexcept ;
|
|
#endif
|
|
|
|
void cfuncReturnNonTrivial(NonTrivial (^_Nonnull)()) noexcept;
|
|
void cfuncReturnNonTrivial2(NonTrivial (*_Nonnull)()) noexcept;
|
|
|
|
struct ARCWeak {
|
|
#if __OBJC__
|
|
__weak _Nullable id m;
|
|
#endif
|
|
};
|
|
|
|
void cfuncARCWeak(void (^ _Nonnull block)(ARCWeak)) noexcept {
|
|
block(ARCWeak());
|
|
}
|
|
|
|
void cfunc(NonTrivial) noexcept;
|
|
void cfuncARCWeak(ARCWeak) noexcept;
|
|
|
|
void (* _Nonnull getFnPtr() noexcept)(NonTrivial) noexcept;
|
|
void (* _Nonnull getFnPtr2() noexcept)(ARCWeak) noexcept;
|
|
|
|
class SharedRef {
|
|
public:
|
|
static SharedRef *_Nonnull makeSharedRef() { return new SharedRef(); }
|
|
int _refCount = 1;
|
|
|
|
private:
|
|
SharedRef() = default;
|
|
|
|
SharedRef(const SharedRef &other) = delete;
|
|
SharedRef &operator=(const SharedRef &other) = delete;
|
|
SharedRef(SharedRef &&other) = delete;
|
|
SharedRef &operator=(SharedRef &&other) = delete;
|
|
} __attribute__((swift_attr("import_reference")))
|
|
__attribute__((swift_attr("retain:retainSharedRef")))
|
|
__attribute__((swift_attr("release:releaseSharedRef")));
|
|
|
|
inline void
|
|
cppGo(void (*_Nonnull takeConstSharedRef)(const SharedRef *_Nonnull x)) {
|
|
SharedRef *ref = SharedRef::makeSharedRef();
|
|
takeConstSharedRef(ref);
|
|
}
|
|
|
|
inline void retainSharedRef(SharedRef *_Nonnull x) { x->_refCount += 1; }
|
|
inline void releaseSharedRef(SharedRef *_Nonnull x) {
|
|
x->_refCount -= 1;
|
|
if (x->_refCount == 0) {
|
|
delete x;
|
|
}
|
|
}
|
|
|
|
#endif // __CLOSURE__
|