Skip to content

Commit 2d03664

Browse files
committed
[TypeLowering] Return pseudogeneric @autoreleasing
Previously, when a pseudogeneric function returned a type parameter, it was unowned. That resulted in invalid OSSA out of SILGen. Here, this is fixed to use the @autoreleasing convention. rdar://64375208
1 parent ed85087 commit 2d03664

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3797,10 +3797,12 @@ namespace {
37973797

37983798
class ObjCSelectorFamilyConventions : public Conventions {
37993799
ObjCSelectorFamily Family;
3800+
bool pseudogeneric;
38003801

38013802
public:
3802-
ObjCSelectorFamilyConventions(ObjCSelectorFamily family)
3803-
: Conventions(ConventionsKind::ObjCSelectorFamily), Family(family) {}
3803+
ObjCSelectorFamilyConventions(ObjCSelectorFamily family, bool pseudogeneric)
3804+
: Conventions(ConventionsKind::ObjCSelectorFamily), Family(family),
3805+
pseudogeneric(pseudogeneric) {}
38043806

38053807
ParameterConvention getIndirectParameter(unsigned index,
38063808
const AbstractionPattern &type,
@@ -3840,8 +3842,9 @@ class ObjCSelectorFamilyConventions : public Conventions {
38403842
// Get the underlying AST type, potentially stripping off one level of
38413843
// optionality while we do it.
38423844
CanType type = tl.getLoweredType().unwrapOptionalType().getASTType();
3843-
if (type->hasRetainablePointerRepresentation()
3844-
|| (type->getSwiftNewtypeUnderlyingType() && !tl.isTrivial()))
3845+
if (type->hasRetainablePointerRepresentation() ||
3846+
(type->getSwiftNewtypeUnderlyingType() && !tl.isTrivial()) ||
3847+
(isa<GenericTypeParamType>(type) && pseudogeneric))
38453848
return ResultConvention::Autoreleased;
38463849

38473850
return ResultConvention::Unowned;
@@ -3871,10 +3874,14 @@ static CanSILFunctionType getSILFunctionTypeForObjCSelectorFamily(
38713874
TypeConverter &TC, ObjCSelectorFamily family, CanAnyFunctionType origType,
38723875
CanAnyFunctionType substInterfaceType, SILExtInfoBuilder extInfoBuilder,
38733876
const ForeignInfo &foreignInfo, std::optional<SILDeclRef> constant) {
3877+
CanGenericSignature genericSig = substInterfaceType.getOptGenericSignature();
3878+
bool pseudogeneric =
3879+
genericSig && constant ? isPseudogeneric(*constant) : false;
38743880
return getSILFunctionType(
38753881
TC, TypeExpansionContext::minimal(), AbstractionPattern(origType),
3876-
substInterfaceType, extInfoBuilder, ObjCSelectorFamilyConventions(family),
3877-
foreignInfo, constant, constant,
3882+
substInterfaceType, extInfoBuilder,
3883+
ObjCSelectorFamilyConventions(family, pseudogeneric), foreignInfo,
3884+
constant, constant,
38783885
/*requirement subs*/ std::nullopt, ProtocolConformanceRef());
38793886
}
38803887

test/PrintAsObjC/extensions.swift

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
// Please keep this file in alphabetical order!
22

33
// RUN: %empty-directory(%t)
4-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-sil-ownership-verifier -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -Xllvm -sil-disable-pass=MandatoryARCOpts
5-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-sil-ownership-verifier -parse-as-library %t/extensions.swiftmodule -typecheck -emit-objc-header-path %t/extensions.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -Xllvm -sil-disable-pass=MandatoryARCOpts
4+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -Xllvm -sil-disable-pass=MandatoryARCOpts
5+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/extensions.swiftmodule -typecheck -emit-objc-header-path %t/extensions.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -Xllvm -sil-disable-pass=MandatoryARCOpts
66
// RUN: %FileCheck %s --input-file %t/extensions.h
77
// RUN: %FileCheck --check-prefix=NEGATIVE %s --input-file %t/extensions.h
88
// RUN: %check-in-clang %t/extensions.h
99

10-
// This test generates invalid SIL. It will cause a compiler assert in
11-
// both -Onone and -O builds:
12-
// Error! Found a leaked owned value that was never consumed.
13-
// -disable-sil-ownership-verifier is a temporary workaround.
14-
// rdar://64375208 (Wrong lowering of PrintAsObjC code. Result is
15-
// unowned instead of autoreleased)
16-
1710
// REQUIRES: objc_interop
1811

1912
import Foundation

test/SILGen/Inputs/usr/include/objc_extensions_helper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
- (void)objCBaseMethod;
55
@property (nonatomic, strong) NSString *prop;
66
@end
7+
8+
@protocol Pettable
9+
@end
10+
11+
@interface PettableContainer<T : id<Pettable>> : NSObject
12+
@end

test/SILGen/objc_extensions.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,10 @@ func testStaticVarAccess() {
185185
// CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]]
186186
_ = Base.x
187187
}
188+
189+
extension PettableContainer {
190+
// CHECK-LABEL: sil private [thunk] [ossa] @$sSo17PettableContainerC15objc_extensionsE7extractxyFTo : $@convention(objc_method) @pseudogeneric <T where T : Pettable> (PettableContainer<T>) -> @autoreleased T
191+
@objc public func extract() -> T { fatalError() }
192+
// CHECK-LABEL: sil private [thunk] [ossa] @$sSo17PettableContainerC15objc_extensionsE8extract2xSgyFTo : $@convention(objc_method) @pseudogeneric <T where T : Pettable> (PettableContainer<T>) -> @autoreleased Optional<T>
193+
@objc public func extract2() -> T? { fatalError() }
194+
}

0 commit comments

Comments
 (0)