Skip to content

Commit 4b0cbc0

Browse files
committed
[Sema] Limit #15280 to Swift 5 mode
1 parent 5f43627 commit 4b0cbc0

File tree

4 files changed

+296
-123
lines changed

4 files changed

+296
-123
lines changed

lib/AST/Decl.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,13 +1309,16 @@ ValueDecl::getAccessSemanticsFromContext(const DeclContext *UseDC,
13091309
assert(isMember && "Access on self, but var isn't a member");
13101310

13111311
// Within a variable's own didSet/willSet specifier, access its storage
1312-
// directly if it's either:
1313-
// 1) A 'plain variable' (i.e a variable that's not a member).
1314-
// 2) An access to the member on the implicit 'self' declaration. If it's a
1315-
// member access on some other base, we want to call the setter as we
1316-
// might be accessing the member on a *different* instance.
1312+
// directly if either:
1313+
// 1) It's a 'plain variable' (i.e a variable that's not a member).
1314+
// 2) It's an access to the member on the implicit 'self' declaration.
1315+
// If it's a member access on some other base, we want to call the setter
1316+
// as we might be accessing the member on a *different* instance.
1317+
// 3) We're not in Swift 5 mode (or higher), as in earlier versions of Swift
1318+
// we always performed direct accesses.
13171319
// This prevents assignments from becoming infinite loops in most cases.
1318-
if (!isMember || isAccessOnSelf)
1320+
if (!isMember || isAccessOnSelf ||
1321+
!UseDC->getASTContext().isSwiftVersionAtLeast(5))
13191322
if (auto *UseFD = dyn_cast<AccessorDecl>(UseDC))
13201323
if (var->hasStorage() && var->hasAccessorFunctions() &&
13211324
UseFD->getStorage() == var)

test/SILGen/properties.swift

Lines changed: 30 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -495,11 +495,6 @@ protocol ForceAccessors {
495495
}
496496

497497
struct DidSetWillSetTests: ForceAccessors {
498-
499-
static var defaultValue: DidSetWillSetTests {
500-
return DidSetWillSetTests(x: 0)
501-
}
502-
503498
// CHECK-LABEL: sil hidden @$S10properties010DidSetWillC5TestsV{{[_0-9a-zA-Z]*}}fC
504499
init(x : Int) {
505500
// Accesses to didset/willset variables are direct in init methods and dtors.
@@ -539,7 +534,7 @@ struct DidSetWillSetTests: ForceAccessors {
539534
// CHECK-NEXT: [[TAKEINTFN:%.*]] = function_ref @$S10properties7takeInt{{[_0-9a-zA-Z]*}}F
540535
// CHECK-NEXT: apply [[TAKEINTFN]](%0) : $@convention(thin) (Int) -> ()
541536

542-
a = zero // reassign, but don't infinite loop, as accessing on 'self'.
537+
a = zero // reassign, but don't infinite loop.
543538

544539
// CHECK-NEXT: // function_ref properties.zero.unsafeMutableAddressor : Swift.Int
545540
// CHECK-NEXT: [[ZEROFN:%.*]] = function_ref @$S10properties4zero{{[_0-9a-zA-Z]*}}vau
@@ -551,63 +546,8 @@ struct DidSetWillSetTests: ForceAccessors {
551546
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
552547
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[WRITE]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
553548
// CHECK-NEXT: assign [[ZERO]] to [[AADDR]]
554-
555-
var unrelatedValue = DidSetWillSetTests.defaultValue
556-
557-
// CHECK: [[BOX:%.*]] = alloc_box ${ var DidSetWillSetTests }, var, name "unrelatedValue"
558-
// CHECK-NEXT: [[BOXADDR:%.*]] = project_box [[BOX]] : ${ var DidSetWillSetTests }, 0
559-
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin DidSetWillSetTests.Type
560-
// CHECK-NEXT: // function_ref static properties.DidSetWillSetTests.defaultValue.getter : properties.DidSetWillSetTests
561-
// CHECK-NEXT: [[DEFAULTVALUE_FN:%.*]] = function_ref @$S10properties{{[_0-9a-zA-Z]*}}vgZ : $@convention(method) (@thin DidSetWillSetTests.Type) -> DidSetWillSetTests
562-
// CHECK-NEXT: [[DEFAULTRESULT:%.*]] = apply [[DEFAULTVALUE_FN]]([[METATYPE]]) : $@convention(method) (@thin DidSetWillSetTests.Type) -> DidSetWillSetTests
563-
// CHECK-NEXT: store [[DEFAULTRESULT]] to [trivial] [[BOXADDR]] : $*DidSetWillSetTests
564-
565-
// But if we re-assign to the property when 'self' is not the base, we should not access directly
566-
// (even though in this example, we *will* infinitely recurse).
567-
unrelatedValue.a = zero
568-
569-
// CHECK-NEXT: // function_ref properties.zero.unsafeMutableAddressor : Swift.Int
570-
// CHECK-NEXT: [[ZEROFN:%.*]] = function_ref @$S10properties4zero{{[_0-9a-zA-Z]*}}vau
571-
// CHECK-NEXT: [[ZERORAW:%.*]] = apply [[ZEROFN]]() : $@convention(thin) () -> Builtin.RawPointer
572-
// CHECK-NEXT: [[ZEROADDR:%.*]] = pointer_to_address [[ZERORAW]] : $Builtin.RawPointer to [strict] $*Int
573-
// CHECK-NEXT: [[READ:%.*]] = begin_access [read] [dynamic] [[ZEROADDR]] : $*Int
574-
// CHECK-NEXT: [[ZERO:%.*]] = load [trivial] [[READ]]
575-
// CHECK-NEXT: end_access [[READ]] : $*Int
576-
577-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] [[BOXADDR]] : $*DidSetWillSetTests
578-
// CHECK-NEXT: // function_ref properties.DidSetWillSetTests.a.setter : Swift.Int
579-
// CHECK-NEXT: [[SETTERFN:%.*]] = function_ref @$S10properties{{[_0-9a-zA-Z]*}}Sivs : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
580-
// CHECK-NEXT: apply [[SETTERFN]]([[ZERO]], [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
581-
// CHECK-NEXT: end_access [[WRITE]] : $*DidSetWillSetTests
582549
}
583550

584-
// This is the synthesized setter for the variable.
585-
586-
// CHECK-LABEL: sil hidden @$S10properties010DidSetWillC5TestsV1aSivs
587-
// CHECK: bb0(%0 : $Int, %1 : $*DidSetWillSetTests):
588-
// CHECK-NEXT: debug_value %0
589-
// CHECK-NEXT: debug_value_addr %1
590-
591-
// CHECK-NEXT: [[READ:%.*]] = begin_access [read] [unknown] %1
592-
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[READ]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
593-
// CHECK-NEXT: [[OLDVAL:%.*]] = load [trivial] [[AADDR]] : $*Int
594-
// CHECK-NEXT: end_access [[READ]]
595-
// CHECK-NEXT: debug_value [[OLDVAL]] : $Int, let, name "tmp"
596-
597-
// CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
598-
// CHECK-NEXT: // function_ref {{.*}}.DidSetWillSetTests.a.willset : Swift.Int
599-
// CHECK-NEXT: [[WILLSETFN:%.*]] = function_ref @$S10properties010DidSetWillC5TestsV1a{{[_0-9a-zA-Z]*}}vw
600-
// CHECK-NEXT: apply [[WILLSETFN]](%0, [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
601-
// CHECK-NEXT: end_access [[WRITE]]
602-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
603-
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[WRITE]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
604-
// CHECK-NEXT: assign %0 to [[AADDR]] : $*Int
605-
// CHECK-NEXT: end_access [[WRITE]]
606-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
607-
// CHECK-NEXT: // function_ref {{.*}}.DidSetWillSetTests.a.didset : Swift.Int
608-
// CHECK-NEXT: [[DIDSETFN:%.*]] = function_ref @$S10properties010DidSetWillC5TestsV1a{{[_0-9a-zA-Z]*}}vW : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
609-
// CHECK-NEXT: apply [[DIDSETFN]]([[OLDVAL]], [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
610-
611551
// CHECK-LABEL: sil hidden @$S10properties010DidSetWillC5TestsV1a{{[_0-9a-zA-Z]*}}vW
612552
didSet {
613553
// CHECK: bb0(%0 : $Int, %1 : $*DidSetWillSetTests):
@@ -624,7 +564,7 @@ struct DidSetWillSetTests: ForceAccessors {
624564
// CHECK-NEXT: [[TAKEINTFN:%.*]] = function_ref @$S10properties7takeInt{{[_0-9a-zA-Z]*}}F
625565
// CHECK-NEXT: apply [[TAKEINTFN]]([[A]]) : $@convention(thin) (Int) -> ()
626566

627-
(self).a = zero // reassign, but don't infinite loop, as accessing on 'self'.
567+
(self).a = zero // reassign, but don't infinite loop.
628568

629569
// CHECK-NEXT: // function_ref properties.zero.unsafeMutableAddressor : Swift.Int
630570
// CHECK-NEXT: [[ZEROFN:%.*]] = function_ref @$S10properties4zero{{[_0-9a-zA-Z]*}}vau
@@ -636,69 +576,42 @@ struct DidSetWillSetTests: ForceAccessors {
636576
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
637577
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[WRITE]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
638578
// CHECK-NEXT: assign [[ZERO]] to [[AADDR]]
639-
640-
var unrelatedValue = DidSetWillSetTests.defaultValue
641-
642-
// CHECK: [[BOX:%.*]] = alloc_box ${ var DidSetWillSetTests }, var, name "unrelatedValue"
643-
// CHECK-NEXT: [[BOXADDR:%.*]] = project_box [[BOX]] : ${ var DidSetWillSetTests }, 0
644-
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin DidSetWillSetTests.Type
645-
// CHECK-NEXT: // function_ref static properties.DidSetWillSetTests.defaultValue.getter : properties.DidSetWillSetTests
646-
// CHECK-NEXT: [[DEFAULTVALUE_FN:%.*]] = function_ref @$S10properties{{[_0-9a-zA-Z]*}}vgZ : $@convention(method) (@thin DidSetWillSetTests.Type) -> DidSetWillSetTests
647-
// CHECK-NEXT: [[DEFAULTRESULT:%.*]] = apply [[DEFAULTVALUE_FN]]([[METATYPE]]) : $@convention(method) (@thin DidSetWillSetTests.Type) -> DidSetWillSetTests
648-
// CHECK-NEXT: store [[DEFAULTRESULT]] to [trivial] [[BOXADDR]] : $*DidSetWillSetTests
649-
650-
// But if we re-assign to the property when 'self' is not the base, we should not access directly
651-
// (even though in this example, we *will* infinitely recurse).
652-
unrelatedValue.a = zero
653-
654-
// CHECK-NEXT: // function_ref properties.zero.unsafeMutableAddressor : Swift.Int
655-
// CHECK-NEXT: [[ZEROFN:%.*]] = function_ref @$S10properties4zero{{[_0-9a-zA-Z]*}}vau
656-
// CHECK-NEXT: [[ZERORAW:%.*]] = apply [[ZEROFN]]() : $@convention(thin) () -> Builtin.RawPointer
657-
// CHECK-NEXT: [[ZEROADDR:%.*]] = pointer_to_address [[ZERORAW]] : $Builtin.RawPointer to [strict] $*Int
658-
// CHECK-NEXT: [[READ:%.*]] = begin_access [read] [dynamic] [[ZEROADDR]] : $*Int
659-
// CHECK-NEXT: [[ZERO:%.*]] = load [trivial] [[READ]]
660-
// CHECK-NEXT: end_access [[READ]] : $*Int
661-
662-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] [[BOXADDR]] : $*DidSetWillSetTests
663-
// CHECK-NEXT: // function_ref properties.DidSetWillSetTests.a.setter : Swift.Int
664-
// CHECK-NEXT: [[SETTERFN:%.*]] = function_ref @$S10properties{{[_0-9a-zA-Z]*}}Sivs : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
665-
// CHECK-NEXT: apply [[SETTERFN]]([[ZERO]], [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
666-
// CHECK-NEXT: end_access [[WRITE]] : $*DidSetWillSetTests
667-
668-
// Even if the value of the base happens to be self...
669-
var other = self
670-
671-
// CHECK: [[BOX:%.*]] = alloc_box ${ var DidSetWillSetTests }, var, name "other"
672-
// CHECK-NEXT: [[BOXADDR:%.*]] = project_box [[BOX]] : ${ var DidSetWillSetTests }, 0
673-
// CHECK-NEXT: [[READ_SELF:%.*]] = begin_access [read] [unknown] %1 : $*DidSetWillSetTests
674-
// CHECK-NEXT: copy_addr [[READ_SELF]] to [initialization] [[BOXADDR]] : $*DidSetWillSetTests
675-
// CHECK-NEXT: end_access [[READ_SELF]] : $*DidSetWillSetTests
676-
677-
other.a = zero
678-
679-
// CHECK-NEXT: // function_ref properties.zero.unsafeMutableAddressor : Swift.Int
680-
// CHECK-NEXT: [[ZEROFN:%.*]] = function_ref @$S10properties4zero{{[_0-9a-zA-Z]*}}vau
681-
// CHECK-NEXT: [[ZERORAW:%.*]] = apply [[ZEROFN]]() : $@convention(thin) () -> Builtin.RawPointer
682-
// CHECK-NEXT: [[ZEROADDR:%.*]] = pointer_to_address [[ZERORAW]] : $Builtin.RawPointer to [strict] $*Int
683-
// CHECK-NEXT: [[READ:%.*]] = begin_access [read] [dynamic] [[ZEROADDR]] : $*Int
684-
// CHECK-NEXT: [[ZERO:%.*]] = load [trivial] [[READ]]
685-
// CHECK-NEXT: end_access [[READ]] : $*Int
686-
687-
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] [[BOXADDR]] : $*DidSetWillSetTests
688-
// CHECK-NEXT: // function_ref properties.DidSetWillSetTests.a.setter : Swift.Int
689-
// CHECK-NEXT: [[SETTERFN:%.*]] = function_ref @$S10properties{{[_0-9a-zA-Z]*}}Sivs : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
690-
// CHECK-NEXT: apply [[SETTERFN]]([[ZERO]], [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
691-
// CHECK-NEXT: end_access [[WRITE]] : $*DidSetWillSetTests
692579
}
693580
}
694581

695-
// This is the synthesized getter for the willSet/didSet variable.
582+
// This is the synthesized getter and setter for the willset/didset variable.
696583

697584
// CHECK-LABEL: sil hidden [transparent] @$S10properties010DidSetWillC5TestsV1aSivg
698585
// CHECK: bb0(%0 : $DidSetWillSetTests):
699586
// CHECK-NEXT: debug_value %0
700587
// CHECK-NEXT: %2 = struct_extract %0 : $DidSetWillSetTests, #DidSetWillSetTests.a
701588
// CHECK-NEXT: return %2 : $Int{{.*}} // id: %3
589+
590+
591+
// CHECK-LABEL: sil hidden @$S10properties010DidSetWillC5TestsV1aSivs
592+
// CHECK: bb0(%0 : $Int, %1 : $*DidSetWillSetTests):
593+
// CHECK-NEXT: debug_value %0
594+
// CHECK-NEXT: debug_value_addr %1
595+
596+
// CHECK-NEXT: [[READ:%.*]] = begin_access [read] [unknown] %1
597+
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[READ]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
598+
// CHECK-NEXT: [[OLDVAL:%.*]] = load [trivial] [[AADDR]] : $*Int
599+
// CHECK-NEXT: end_access [[READ]]
600+
// CHECK-NEXT: debug_value [[OLDVAL]] : $Int, let, name "tmp"
601+
602+
// CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
603+
// CHECK-NEXT: // function_ref {{.*}}.DidSetWillSetTests.a.willset : Swift.Int
604+
// CHECK-NEXT: [[WILLSETFN:%.*]] = function_ref @$S10properties010DidSetWillC5TestsV1a{{[_0-9a-zA-Z]*}}vw
605+
// CHECK-NEXT: apply [[WILLSETFN]](%0, [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
606+
// CHECK-NEXT: end_access [[WRITE]]
607+
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
608+
// CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[WRITE]] : $*DidSetWillSetTests, #DidSetWillSetTests.a
609+
// CHECK-NEXT: assign %0 to [[AADDR]] : $*Int
610+
// CHECK-NEXT: end_access [[WRITE]]
611+
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [unknown] %1
612+
// CHECK-NEXT: // function_ref {{.*}}.DidSetWillSetTests.a.didset : Swift.Int
613+
// CHECK-NEXT: [[DIDSETFN:%.*]] = function_ref @$S10properties010DidSetWillC5TestsV1a{{[_0-9a-zA-Z]*}}vW : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
614+
// CHECK-NEXT: apply [[DIDSETFN]]([[OLDVAL]], [[WRITE]]) : $@convention(method) (Int, @inout DidSetWillSetTests) -> ()
702615
}
703616

704617

@@ -748,7 +661,7 @@ func force_global_observing_property_setter() {
748661
global_observing_property = x
749662
}
750663

751-
// global_observing_property's setter needs to call didSet implementation.
664+
// global_observing_property's setter needs to call didSet.
752665

753666
// CHECK-LABEL: sil hidden @$S10properties25global_observing_property{{[_0-9a-zA-Z]*}}vs
754667
// CHECK: function_ref properties.global_observing_property.unsafeMutableAddressor

0 commit comments

Comments
 (0)