@@ -695,18 +695,10 @@ struct AccessState {
695
695
};
696
696
} // namespace
697
697
698
- // / For each argument in the range of the callee arguments being applied at the
699
- // / given apply site, use the summary analysis to determine whether the
700
- // / arguments will be accessed in a way that conflicts with any currently in
701
- // / progress accesses. If so, diagnose.
702
- static void checkCaptureAccess (ApplySite Apply, AccessState &State) {
703
- SILFunction *Callee = Apply.getCalleeFunction ();
704
- if (!Callee || Callee->empty ())
705
- return ;
706
-
707
- const AccessSummaryAnalysis::FunctionSummary &FS =
708
- State.ASA ->getOrCreateSummary (Callee);
709
-
698
+ // Find conflicting access on each argument using AccessSummaryAnalysis.
699
+ static void
700
+ checkCaptureAccess (ApplySite Apply, AccessState &State,
701
+ const AccessSummaryAnalysis::FunctionSummary &FS) {
710
702
for (unsigned ArgumentIndex : range (Apply.getNumArguments ())) {
711
703
712
704
unsigned CalleeIndex =
@@ -724,7 +716,7 @@ static void checkCaptureAccess(ApplySite Apply, AccessState &State) {
724
716
SILValue Argument = Apply.getArgument (ArgumentIndex);
725
717
assert (Argument->getType ().isAddress ());
726
718
727
- // A valid AccessedStorage should alway sbe found because Unsafe accesses
719
+ // A valid AccessedStorage should always be found because Unsafe accesses
728
720
// are not tracked by AccessSummaryAnalysis.
729
721
const AccessedStorage &Storage = findValidAccessedStorage (Argument);
730
722
auto AccessIt = State.Accesses ->find (Storage);
@@ -739,6 +731,50 @@ static void checkCaptureAccess(ApplySite Apply, AccessState &State) {
739
731
}
740
732
}
741
733
734
+ // / For each argument in the range of the callee arguments being applied at the
735
+ // / given apply site, use the summary analysis to determine whether the
736
+ // / arguments will be accessed in a way that conflicts with any currently in
737
+ // / progress accesses. If so, diagnose.
738
+ static void checkCaptureAccess (ApplySite Apply, AccessState &State) {
739
+ // A callee may be nullptr or empty for various reasons, such as being
740
+ // dynamically replaceable.
741
+ SILFunction *Callee = Apply.getCalleeFunction ();
742
+ if (Callee && !Callee->empty ()) {
743
+ checkCaptureAccess (Apply, State, State.ASA ->getOrCreateSummary (Callee));
744
+ return ;
745
+ }
746
+ // In the absence of AccessSummaryAnalysis, conservatively assume by-address
747
+ // captures are fully accessed by the callee.
748
+ for (Operand &argOper : Apply.getArgumentOperands ()) {
749
+ auto convention = Apply.getArgumentConvention (argOper);
750
+ if (convention != SILArgumentConvention::Indirect_InoutAliasable)
751
+ continue ;
752
+
753
+ // A valid AccessedStorage should always be found because Unsafe accesses
754
+ // are not tracked by AccessSummaryAnalysis.
755
+ const AccessedStorage &Storage = findValidAccessedStorage (argOper.get ());
756
+
757
+ // Are there any accesses in progress at the time of the call?
758
+ auto AccessIt = State.Accesses ->find (Storage);
759
+ if (AccessIt == State.Accesses ->end ())
760
+ continue ;
761
+
762
+ // The unknown argument access is considered a modify of the root subpath.
763
+ auto argAccess = RecordedAccess (SILAccessKind::Modify, Apply.getLoc (),
764
+ State.ASA ->getSubPathTrieRoot ());
765
+
766
+ // Construct a conflicting RecordedAccess if one doesn't already exist.
767
+ const AccessInfo &info = AccessIt->getSecond ();
768
+ auto inProgressAccess =
769
+ shouldReportAccess (info, SILAccessKind::Modify, argAccess.getSubPath ());
770
+ if (!inProgressAccess)
771
+ continue ;
772
+
773
+ State.ConflictingAccesses .emplace_back (Storage, *inProgressAccess,
774
+ argAccess);
775
+ }
776
+ }
777
+
742
778
// / If the given values has a SILFunctionType or an Optional<SILFunctionType>,
743
779
// / return the SILFunctionType. Otherwise, return an invalid type.
744
780
static CanSILFunctionType getSILFunctionTypeForValue (SILValue arg) {
0 commit comments