Skip to content

Commit ef798d5

Browse files
authored
Merge pull request #83090 from eeckstein/fix-pre-specialization
GenericSpecializer: don't pre-specialize C++ reference type for AnyObject
2 parents 213ad8a + f962d76 commit ef798d5

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

include/swift/AST/Types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
12641264
/// representation, i.e. whether it is representable as a single,
12651265
/// possibly nil pointer that can be unknown-retained and
12661266
/// unknown-released.
1267+
/// This does not include C++ imported `SWIFT_SHARED_REFERENCE` classes.
1268+
/// They act as Swift classes but are not compatible with Swift's
1269+
/// retain/release runtime functions.
12671270
bool hasRetainablePointerRepresentation();
12681271

12691272
/// Given that this type is a reference type, which kind of reference

include/swift/SIL/SILType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ class SILType {
419419

420420
/// Returns true if the referenced type is guaranteed to have a
421421
/// single-retainable-pointer representation.
422+
/// This does not include C++ imported `SWIFT_SHARED_REFERENCE` classes.
423+
/// They act as Swift classes but are not compatible with Swift's
424+
/// retain/release runtime functions.
422425
bool hasRetainablePointerRepresentation() const {
423426
return getASTType()->hasRetainablePointerRepresentation();
424427
}

lib/AST/Type.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,11 @@ static bool hasRetainablePointerRepresentation(CanType type) {
28442844
type = objType;
28452845
}
28462846

2847+
// C++ imported `SWIFT_SHARED_REFERENCE` classes are not compatible with
2848+
// Swift's retain/release runtime functions.
2849+
if (type.isForeignReferenceType())
2850+
return false;
2851+
28472852
return isBridgeableObjectType(type);
28482853
}
28492854

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %swiftc_driver -O -I %t/Inputs %t/test.swift -cxx-interoperability-mode=default -I %swift_src_root/lib/ClangImporter/SwiftBridging -o %t/a.out
4+
// RUN: %target-codesign %t/a.out
5+
// RUN: %target-run %t/a.out | %FileCheck %s
6+
7+
// REQUIRES: executable_test
8+
// UNSUPPORTED: back_deployment_runtime
9+
10+
// Metadata for foreign reference types is not supported on Windows.
11+
// UNSUPPORTED: OS=windows-msvc
12+
13+
//--- Inputs/module.modulemap
14+
15+
module Test {
16+
header "reftype.h"
17+
requires cplusplus
18+
}
19+
20+
//--- Inputs/reftype.h
21+
22+
#include "swift/bridging"
23+
24+
class RefType {
25+
public:
26+
static RefType* _Nonnull makeRefType() SWIFT_RETURNS_RETAINED {
27+
return new RefType();
28+
}
29+
30+
private:
31+
RefType() : _refCount(1) {
32+
}
33+
RefType(const RefType&) = delete;
34+
RefType& operator=(const RefType&) = delete;
35+
~RefType() {
36+
}
37+
38+
inline friend void retainRefType(RefType* _Nonnull x) {
39+
x->_refCount += 1;
40+
41+
}
42+
inline friend void releaseRefType(RefType* _Nonnull x) {
43+
x->_refCount -= 1;
44+
if (x->_refCount == 0) {
45+
delete x;
46+
}
47+
}
48+
49+
int _refCount;
50+
} SWIFT_SHARED_REFERENCE(retainRefType, releaseRefType);
51+
52+
//--- test.swift
53+
54+
import Test
55+
56+
@inline(never)
57+
func go() {
58+
let x: RefType = RefType.makeRefType()
59+
var y: [RefType] = []
60+
y.append(x)
61+
// CHECK: 1
62+
print(y.count)
63+
}
64+
65+
go()
66+

0 commit comments

Comments
 (0)