Skip to content

Commit 3d3331f

Browse files
authored
Merge pull request #83787 from egorzhdan/egorzhdan/weak-reference
[cxx-interop] Prohibit weak references to foreign reference types
2 parents 86ea012 + 9abadf5 commit 3d3331f

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6357,6 +6357,9 @@ ERROR(invalid_ownership_protocol_type,none,
63576357
ERROR(invalid_ownership_incompatible_class,none,
63586358
"%0 is incompatible with %1 references",
63596359
(Type, ReferenceOwnership))
6360+
ERROR(invalid_ownership_incompatible_foreign_reference_type,none,
6361+
"%0 is incompatible with 'weak' references, because it is a foreign reference type",
6362+
(Type))
63606363
ERROR(invalid_ownership_with_optional,none,
63616364
"%0 variable cannot have optional type", (ReferenceOwnership))
63626365
ERROR(invalid_ownership_not_optional,none,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5452,13 +5452,28 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
54525452
}
54535453

54545454
ClassDecl *underlyingClass = underlyingType->getClassOrBoundGenericClass();
5455-
if (underlyingClass && underlyingClass->isIncompatibleWithWeakReferences()) {
5456-
Diags
5457-
.diagnose(attr->getLocation(),
5458-
diag::invalid_ownership_incompatible_class, underlyingType,
5459-
ownershipKind)
5460-
.fixItRemove(attr->getRange());
5461-
attr->setInvalid();
5455+
if (underlyingClass) {
5456+
if (underlyingClass->isIncompatibleWithWeakReferences()) {
5457+
Diags
5458+
.diagnose(attr->getLocation(),
5459+
diag::invalid_ownership_incompatible_class, underlyingType,
5460+
ownershipKind)
5461+
.fixItRemove(attr->getRange());
5462+
attr->setInvalid();
5463+
}
5464+
// Foreign reference types cannot be held as weak references, since the
5465+
// Swift runtime has no way to make the pointer null when the object is
5466+
// deallocated.
5467+
// Unowned references to foreign reference types are supported.
5468+
if (ownershipKind == ReferenceOwnership::Weak &&
5469+
underlyingClass->isForeignReferenceType()) {
5470+
Diags
5471+
.diagnose(attr->getLocation(),
5472+
diag::invalid_ownership_incompatible_foreign_reference_type,
5473+
underlyingType)
5474+
.fixItRemove(attr->getRange());
5475+
attr->setInvalid();
5476+
}
54625477
}
54635478

54645479
auto PDC = dyn_cast<ProtocolDecl>(dc);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift -cxx-interoperability-mode=default -I %S/Inputs -disable-availability-checking
2+
3+
import POD
4+
5+
struct HasWeakReference {
6+
weak var x: Empty? // expected-error {{'Empty' is incompatible with 'weak' references, because it is a foreign reference type}}
7+
}
8+
9+
struct HasUnownedReference {
10+
unowned var x: Empty!
11+
}

0 commit comments

Comments
 (0)