mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #83815 from egorzhdan/egorzhdan/6.2-retain-release-unsigned
🍒[cxx-interop] Allow retain/release operations to return an unsigned integer
This commit is contained in:
@@ -256,11 +256,11 @@ ERROR(foreign_reference_types_invalid_retain_release, none,
|
||||
|
||||
ERROR(foreign_reference_types_retain_non_void_or_self_return_type, none,
|
||||
"specified retain function '%0' is invalid; "
|
||||
"retain function must have 'void' or parameter return type",
|
||||
"retain function must either return have 'void', the reference count as an integer, or the parameter type",
|
||||
(StringRef))
|
||||
ERROR(foreign_reference_types_release_non_void_return_type, none,
|
||||
"specified release function '%0' is invalid; "
|
||||
"release function must have 'void' return type",
|
||||
"release function must either return 'void' or the reference count as an integer",
|
||||
(StringRef))
|
||||
ERROR(foreign_reference_types_retain_release_not_a_function_decl, none,
|
||||
"specified %select{retain|release}0 function '%1' is not a function",
|
||||
|
||||
@@ -2717,7 +2717,7 @@ namespace {
|
||||
|
||||
enum class RetainReleaseOperationKind {
|
||||
notAfunction,
|
||||
doesntReturnVoidOrSelf,
|
||||
invalidReturnType,
|
||||
invalidParameters,
|
||||
valid
|
||||
};
|
||||
@@ -2745,10 +2745,20 @@ namespace {
|
||||
// The return type should be void (for release functions), or void
|
||||
// or the parameter type (for retain functions).
|
||||
auto resultInterfaceType = operationFn->getResultInterfaceType();
|
||||
if (!resultInterfaceType->isVoid()) {
|
||||
if (!resultInterfaceType->isVoid() &&
|
||||
!resultInterfaceType->isUInt() &&
|
||||
!resultInterfaceType->isUInt8() &&
|
||||
!resultInterfaceType->isUInt16() &&
|
||||
!resultInterfaceType->isUInt32() &&
|
||||
!resultInterfaceType->isUInt64() &&
|
||||
!resultInterfaceType->isInt() &&
|
||||
!resultInterfaceType->isInt8() &&
|
||||
!resultInterfaceType->isInt16() &&
|
||||
!resultInterfaceType->isInt32() &&
|
||||
!resultInterfaceType->isInt64()) {
|
||||
if (operationKind == CustomRefCountingOperationKind::release ||
|
||||
!resultInterfaceType->lookThroughSingleOptionalType()->isEqual(paramType))
|
||||
return RetainReleaseOperationKind::doesntReturnVoidOrSelf;
|
||||
return RetainReleaseOperationKind::invalidReturnType;
|
||||
}
|
||||
|
||||
// The parameter of the retain/release function should be pointer to the
|
||||
@@ -2813,7 +2823,7 @@ namespace {
|
||||
diag::foreign_reference_types_retain_release_not_a_function_decl,
|
||||
false, retainOperation.name);
|
||||
break;
|
||||
case RetainReleaseOperationKind::doesntReturnVoidOrSelf:
|
||||
case RetainReleaseOperationKind::invalidReturnType:
|
||||
Impl.diagnose(
|
||||
loc,
|
||||
diag::foreign_reference_types_retain_non_void_or_self_return_type,
|
||||
@@ -2878,7 +2888,7 @@ namespace {
|
||||
diag::foreign_reference_types_retain_release_not_a_function_decl,
|
||||
true, releaseOperation.name);
|
||||
break;
|
||||
case RetainReleaseOperationKind::doesntReturnVoidOrSelf:
|
||||
case RetainReleaseOperationKind::invalidReturnType:
|
||||
Impl.diagnose(
|
||||
loc,
|
||||
diag::foreign_reference_types_release_non_void_return_type,
|
||||
|
||||
@@ -64,6 +64,20 @@ GlobalCountNullableInit {
|
||||
inline void GCRetainNullableInit(GlobalCountNullableInit *x) { globalCount++; }
|
||||
inline void GCReleaseNullableInit(GlobalCountNullableInit *x) { globalCount--; }
|
||||
|
||||
struct __attribute__((swift_attr("import_as_ref")))
|
||||
__attribute__((swift_attr("retain:RCRetain")))
|
||||
__attribute__((swift_attr("release:RCRelease"))) HasOpsReturningRefCount final {
|
||||
int refCount = 0;
|
||||
|
||||
static HasOpsReturningRefCount *create() {
|
||||
return new (malloc(sizeof(HasOpsReturningRefCount)))
|
||||
HasOpsReturningRefCount();
|
||||
}
|
||||
};
|
||||
|
||||
inline unsigned RCRetain(HasOpsReturningRefCount *x) { return ++x->refCount; }
|
||||
inline unsigned RCRelease(HasOpsReturningRefCount *x) { return --x->refCount; }
|
||||
|
||||
SWIFT_END_NULLABILITY_ANNOTATIONS
|
||||
|
||||
#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_REFERENCE_COUNTED_H
|
||||
|
||||
@@ -25,7 +25,7 @@ struct
|
||||
__attribute__((swift_attr("release:badRelease")))
|
||||
BadRetainRelease {};
|
||||
|
||||
int badRetain(BadRetainRelease *v);
|
||||
float badRetain(BadRetainRelease *v);
|
||||
void badRelease(BadRetainRelease *v, int i);
|
||||
|
||||
struct
|
||||
@@ -235,7 +235,7 @@ public func test(x: NonExistent) { }
|
||||
@available(macOS 13.3, *)
|
||||
public func test(x: NoRetainRelease) { }
|
||||
|
||||
// CHECK: error: specified retain function 'badRetain' is invalid; retain function must have 'void' or parameter return type
|
||||
// CHECK: error: specified retain function 'badRetain' is invalid; retain function must either return have 'void', the reference count as an integer, or the parameter type
|
||||
// CHECK: error: specified release function 'badRelease' is invalid; release function must have exactly one argument of type 'BadRetainRelease'
|
||||
@available(macOS 13.3, *)
|
||||
public func test(x: BadRetainRelease) { }
|
||||
|
||||
@@ -17,6 +17,19 @@ public func getLocalCount() -> NS.LocalCount {
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
public func useRetainReleaseOpsReturningRefCount() -> HasOpsReturningRefCount {
|
||||
let result = HasOpsReturningRefCount.create()
|
||||
return result
|
||||
}
|
||||
|
||||
// CHECK: define {{.*}}swiftcc ptr @"$s4main36useRetainReleaseOpsReturningRefCountSo03HasefgH0VyF"()
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK: %0 = call ptr @{{_ZN23HasOpsReturningRefCount6createEv|"\?create\@HasOpsReturningRefCount\@\@SAPEAU1\@XZ"}}()
|
||||
// CHECK: %1 = call i32 @{{_Z8RCRetainP23HasOpsReturningRefCount|"\?RCRetain\@\@YAIPEAUHasOpsReturningRefCount\@\@\@Z"}}(ptr %0)
|
||||
// CHECK: ret ptr %0
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
public func get42() -> Int32 {
|
||||
let result = NS.LocalCount.create()
|
||||
return result.returns42()
|
||||
|
||||
Reference in New Issue
Block a user