Skip to content

[4.0] [Exclusivity] Relax closure enforcement on separate stored properties… #10860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

devincoughlin
Copy link
Contributor

… (#10789)

Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:

struct MyStruct {
var x = X()
var y = Y()

mutating
func foo() {
x.mutatesAndTakesClosure() {
_ = y.read() // no-warning
}
}
}

To do this, update the access summary analysis to summarize accesses to
subpaths of a capture.

rdar://problem/32987932

…swiftlang#10789)

Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:

struct MyStruct {
   var x = X()
   var y = Y()

  mutating
  func foo() {
    x.mutatesAndTakesClosure() {
      _ = y.read() // no-warning
   }
  }
}

To do this, update the access summary analysis to summarize accesses to
subpaths of a capture.

rdar://problem/32987932
@devincoughlin devincoughlin requested a review from atrick July 10, 2017 21:55
@devincoughlin
Copy link
Contributor Author

@atrick Would you mind reviewing for CCC inclusion into swift-4.0-branch?

@devincoughlin devincoughlin changed the title [Exclusivity] Relax closure enforcement on separate stored properties… [4.0] [Exclusivity] Relax closure enforcement on separate stored properties… Jul 10, 2017
@devincoughlin
Copy link
Contributor Author

@swift-ci Please test

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥇 CCC reviewed for 4.0.
@devincoughlin This looks great! Very glad it's going into 4.0.
The three "TODO" comments do not need to be addressed in 4.0. They are for future follow-up.

bool changed = false;

const SubAccessMap &otherAccesses = other.SubAccesses;
for (auto it = otherAccesses.begin(), e = otherAccesses.end(); it != e;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Add a comment explaining why nondeterministic iteration order yields deterministic results (the merge order can affect the DenseMap's internal state, but not it's semantics--iterating over the final result is nondeterministic anyway).

Optional<RecordedAccess> BestInProgressAccess;
Optional<RecordedAccess> BestArgAccess;

for (const auto &MapPair : AS.getSubAccesses()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Again, this is iterating over a DenseMap. Since only the "best" conflict is selected, it probably doesn't matter. But this assumptions needs to be clearly commented.

const auto &SubAccesses = AS.getSubAccesses();

// Is the capture accessed in the callee?
if (SubAccesses.size() == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: could be if (AS.getSubAccesses().empty())

@devincoughlin
Copy link
Contributor Author

CCC Information:
Explanation: The existing static diagnostics that enforce exclusive access to memory
for noescape closures treat an access to a struct property as an access to a whole
struct. This results in false positives when a mutating method called on one stored property
of a struct takes a noescape closure that accesses another stored property. This
change refines the analysis to track accesses on a per-stored-property basis to
avoid these false positives. This is the final piece of the exclusive access model for Swift 4.0.

Scope: This is not a source-breaking change. It results in fewer diagnostics being
emitted. The false positives this fixes are relatively rare, but there is one project in the
Source Compatibility Suite that this will remove diagnostics on.

Radar (and possibly SR Issue): rdar://problem/32987932
Risk: This is a a low-to-medium risk change. It changes a SIL diagnostic analysis that
runs on all noescape closures. The specific risk is the possibility of a compiler
crash.

Testing: I've extended the unit tests and run the change on the Source Compatibility
Suite (with assertions enabled).

@devincoughlin
Copy link
Contributor Author

Aproved by @bob-wilson for CCC.

@devincoughlin
Copy link
Contributor Author

@swift-ci Please smoke test and merge

@swift-ci swift-ci merged commit a35947a into swiftlang:swift-4.0-branch Jul 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants