Skip to content

Commit deb32b2

Browse files
authored
Merge pull request #27642 from DougGregor/property-wrappers-di-access
2 parents d034d2d + f9f63bd commit deb32b2

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,19 +1366,30 @@ namespace {
13661366
std::move(value), isSelfParameter);
13671367
}
13681368

1369+
/// Determine whether the backing variable for the given
1370+
/// property (that has a wrapper) is visible from the
1371+
/// current context.
1372+
static bool isBackingVarVisible(VarDecl *field,
1373+
DeclContext *fromDC){
1374+
VarDecl *backingVar = field->getPropertyWrapperBackingProperty();
1375+
return backingVar->isAccessibleFrom(fromDC);
1376+
}
1377+
13691378
void set(SILGenFunction &SGF, SILLocation loc,
13701379
ArgumentSource &&value, ManagedValue base) && override {
13711380
assert(getAccessorDecl()->isSetter());
13721381
SILDeclRef setter = Accessor;
13731382

1374-
if (hasPropertyWrapper() && IsOnSelfParameter) {
1383+
if (hasPropertyWrapper() && IsOnSelfParameter &&
1384+
isBackingVarVisible(cast<VarDecl>(Storage),
1385+
SGF.FunctionDC)) {
13751386
// This is wrapped property. Instead of emitting a setter, emit an
13761387
// assign_by_wrapper with the allocating initializer function and the
13771388
// setter function as arguments. DefiniteInitializtion will then decide
13781389
// between the two functions, depending if it's an initialization or a
13791390
// re-assignment.
13801391
//
1381-
VarDecl *field = dyn_cast<VarDecl>(Storage);
1392+
VarDecl *field = cast<VarDecl>(Storage);
13821393
VarDecl *backingVar = field->getPropertyWrapperBackingProperty();
13831394
assert(backingVar);
13841395
CanType ValType =

test/SILGen/Inputs/property_wrapper_defs.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ public struct MyPublished<Value> {
1616
set { self = newValue }
1717
}
1818
}
19+
20+
public class UsesMyPublished {
21+
@MyPublished public var foo: Int = 17
22+
}

test/SILGen/property_wrappers.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,17 @@ open class TestMyWrapper {
508508
@MyWrapper open var useMyWrapper: Int? = nil
509509
}
510510

511+
// rdar://problem/54352235 - crash due to reference to private backing var
512+
extension UsesMyPublished {
513+
// CHECK-LABEL: sil hidden [ossa] @$s21property_wrapper_defs15UsesMyPublishedC0A9_wrappersE6setFooyySiF : $@convention(method) (Int, @guaranteed UsesMyPublished) -> ()
514+
// CHECK: class_method %1 : $UsesMyPublished, #UsesMyPublished.foo!setter.1
515+
// CHECK-NOT: assign_by_wrapper
516+
// CHECK: return
517+
func setFoo(_ x: Int) {
518+
foo = x
519+
}
520+
}
521+
511522
// CHECK-LABEL: sil_vtable ClassUsingWrapper {
512523
// CHECK-NEXT: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter
513524
// CHECK-NEXT: #ClassUsingWrapper.x!setter.1: (ClassUsingWrapper) -> (Int) -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivs // ClassUsingWrapper.x.setter

0 commit comments

Comments
 (0)