Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,20 @@ static FuncDecl *addMaterializeForSet(AbstractStorageDecl *storage,
storage->getSetter());
storage->setMaterializeForSetFunc(materializeForSet);

// Make sure we record the override.
//
// FIXME: Instead, we should just not call checkOverrides() on
// storage until all accessors are in place.
if (auto *baseASD = storage->getOverriddenDecl()) {
// If the base storage has a private setter, we're not overriding
// materializeForSet either.
auto *baseMFS = baseASD->getMaterializeForSetFunc();
if (baseMFS != nullptr &&
baseASD->isSetterAccessibleFrom(storage->getDeclContext())) {
materializeForSet->setOverriddenDecl(baseMFS);
}
}

return materializeForSet;
}

Expand Down
26 changes: 26 additions & 0 deletions test/Interpreter/classes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,29 @@ func makeOne<T : Makeable>(_: T.Type) -> T {
}

makeOne(Child.self).doSomething() // CHECK: Heaven!

// https://bugs.swift.org/browse/SR-3840

class BaseProperty {
var value: Int {
get { fatalError() }
set { fatalError() }
}

func increment() -> Self {
value += 1
return self
}
}

class DerivedProperty : BaseProperty {
override var value: Int {
get { return _value }
set { _value = newValue }
}

var _value: Int = 0
}

// CHECK: 1
print(DerivedProperty().increment().value)
24 changes: 24 additions & 0 deletions test/SILGen/materializeForSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,21 @@ func inoutAccessOfStaticProperty<T : Beverage>(_ t: T.Type) {
increment(&t.abv)
}

// Test for materializeForSet vs overriden computed property of classes.
class BaseForOverride {
var valueStored: Int
var valueComputed: Int { get { } set { } }

init(valueStored: Int) {
self.valueStored = valueStored
}
}

class DerivedForOverride : BaseForOverride {
override var valueStored: Int { get { } set { } }
override var valueComputed: Int { get { } set { } }
}

// Test for materializeForSet vs static properties of classes.

class ReferenceBeer {
Expand Down Expand Up @@ -514,6 +529,15 @@ func testMaterializedSetter() {
f.computed = f.computed
}

// CHECK-LABEL: sil_vtable DerivedForOverride {
// CHECK: #BaseForOverride.valueComputed!getter.1: (BaseForOverride) -> () -> Int : _T017materializeForSet07DerivedB8OverrideC13valueComputedSifg
// CHECK: #BaseForOverride.valueComputed!setter.1: (BaseForOverride) -> (Int) -> () : _T017materializeForSet07DerivedB8OverrideC13valueComputedSifs
// CHECK: #BaseForOverride.valueComputed!materializeForSet.1: (BaseForOverride) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?) : _T017materializeForSet07DerivedB8OverrideC13valueComputedSifm
// CHECK: #BaseForOverride.valueStored!getter.1: (BaseForOverride) -> () -> Int : _T017materializeForSet07DerivedB8OverrideC11valueStoredSifg
// CHECK: #BaseForOverride.valueStored!setter.1: (BaseForOverride) -> (Int) -> () : _T017materializeForSet07DerivedB8OverrideC11valueStoredSifs
// CHECK: #BaseForOverride.valueStored!materializeForSet.1: (BaseForOverride) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?) : _T017materializeForSet07DerivedB8OverrideC11valueStoredSifm
// CHECK: }

// CHECK-LABEL: sil_witness_table hidden Bill: Totalled module materializeForSet {
// CHECK: method #Totalled.total!getter.1: {{.*}} : @_T017materializeForSet4BillVAA8TotalledAaaDP5totalSifgTW
// CHECK: method #Totalled.total!setter.1: {{.*}} : @_T017materializeForSet4BillVAA8TotalledAaaDP5totalSifsTW
Expand Down