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,
|
ERROR(foreign_reference_types_retain_non_void_or_self_return_type, none,
|
||||||
"specified retain function '%0' is invalid; "
|
"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))
|
(StringRef))
|
||||||
ERROR(foreign_reference_types_release_non_void_return_type, none,
|
ERROR(foreign_reference_types_release_non_void_return_type, none,
|
||||||
"specified release function '%0' is invalid; "
|
"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))
|
(StringRef))
|
||||||
ERROR(foreign_reference_types_retain_release_not_a_function_decl, none,
|
ERROR(foreign_reference_types_retain_release_not_a_function_decl, none,
|
||||||
"specified %select{retain|release}0 function '%1' is not a function",
|
"specified %select{retain|release}0 function '%1' is not a function",
|
||||||
|
|||||||
@@ -2717,7 +2717,7 @@ namespace {
|
|||||||
|
|
||||||
enum class RetainReleaseOperationKind {
|
enum class RetainReleaseOperationKind {
|
||||||
notAfunction,
|
notAfunction,
|
||||||
doesntReturnVoidOrSelf,
|
invalidReturnType,
|
||||||
invalidParameters,
|
invalidParameters,
|
||||||
valid
|
valid
|
||||||
};
|
};
|
||||||
@@ -2745,10 +2745,20 @@ namespace {
|
|||||||
// The return type should be void (for release functions), or void
|
// The return type should be void (for release functions), or void
|
||||||
// or the parameter type (for retain functions).
|
// or the parameter type (for retain functions).
|
||||||
auto resultInterfaceType = operationFn->getResultInterfaceType();
|
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 ||
|
if (operationKind == CustomRefCountingOperationKind::release ||
|
||||||
!resultInterfaceType->lookThroughSingleOptionalType()->isEqual(paramType))
|
!resultInterfaceType->lookThroughSingleOptionalType()->isEqual(paramType))
|
||||||
return RetainReleaseOperationKind::doesntReturnVoidOrSelf;
|
return RetainReleaseOperationKind::invalidReturnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The parameter of the retain/release function should be pointer to the
|
// 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,
|
diag::foreign_reference_types_retain_release_not_a_function_decl,
|
||||||
false, retainOperation.name);
|
false, retainOperation.name);
|
||||||
break;
|
break;
|
||||||
case RetainReleaseOperationKind::doesntReturnVoidOrSelf:
|
case RetainReleaseOperationKind::invalidReturnType:
|
||||||
Impl.diagnose(
|
Impl.diagnose(
|
||||||
loc,
|
loc,
|
||||||
diag::foreign_reference_types_retain_non_void_or_self_return_type,
|
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,
|
diag::foreign_reference_types_retain_release_not_a_function_decl,
|
||||||
true, releaseOperation.name);
|
true, releaseOperation.name);
|
||||||
break;
|
break;
|
||||||
case RetainReleaseOperationKind::doesntReturnVoidOrSelf:
|
case RetainReleaseOperationKind::invalidReturnType:
|
||||||
Impl.diagnose(
|
Impl.diagnose(
|
||||||
loc,
|
loc,
|
||||||
diag::foreign_reference_types_release_non_void_return_type,
|
diag::foreign_reference_types_release_non_void_return_type,
|
||||||
|
|||||||
@@ -64,6 +64,20 @@ GlobalCountNullableInit {
|
|||||||
inline void GCRetainNullableInit(GlobalCountNullableInit *x) { globalCount++; }
|
inline void GCRetainNullableInit(GlobalCountNullableInit *x) { globalCount++; }
|
||||||
inline void GCReleaseNullableInit(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
|
SWIFT_END_NULLABILITY_ANNOTATIONS
|
||||||
|
|
||||||
#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_REFERENCE_COUNTED_H
|
#endif // TEST_INTEROP_CXX_FOREIGN_REFERENCE_INPUTS_REFERENCE_COUNTED_H
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct
|
|||||||
__attribute__((swift_attr("release:badRelease")))
|
__attribute__((swift_attr("release:badRelease")))
|
||||||
BadRetainRelease {};
|
BadRetainRelease {};
|
||||||
|
|
||||||
int badRetain(BadRetainRelease *v);
|
float badRetain(BadRetainRelease *v);
|
||||||
void badRelease(BadRetainRelease *v, int i);
|
void badRelease(BadRetainRelease *v, int i);
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@@ -235,7 +235,7 @@ public func test(x: NonExistent) { }
|
|||||||
@available(macOS 13.3, *)
|
@available(macOS 13.3, *)
|
||||||
public func test(x: NoRetainRelease) { }
|
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'
|
// CHECK: error: specified release function 'badRelease' is invalid; release function must have exactly one argument of type 'BadRetainRelease'
|
||||||
@available(macOS 13.3, *)
|
@available(macOS 13.3, *)
|
||||||
public func test(x: BadRetainRelease) { }
|
public func test(x: BadRetainRelease) { }
|
||||||
|
|||||||
@@ -17,6 +17,19 @@ public func getLocalCount() -> NS.LocalCount {
|
|||||||
// CHECK-NEXT: }
|
// 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 {
|
public func get42() -> Int32 {
|
||||||
let result = NS.LocalCount.create()
|
let result = NS.LocalCount.create()
|
||||||
return result.returns42()
|
return result.returns42()
|
||||||
|
|||||||
Reference in New Issue
Block a user