There's a longstanding problem in implementing `-isEqualToString:`,
where if you don't know how to get fast access to the other NSString's
contents, you have to pick between doing it character by character (very
slow), or calling [other isEqualToString: self], which risks infinite
recursion if the other string does the same.
This cuts the gordian knot by adding a new method
`isEqualToBytes:encoding:count:`, so you can get the contents out of
`self`, and hand it to the other string, confident that it will not need
to (nor, in fact be able to) ask you anything that might recurse.
Previously, we skipped checking the return type of a function for safety
as we expected to warn at the use of the returned value:
let x = returnsUnsafe()
usesUnsafe(x) // warn here
Unfortunately, this resulted in missing some unsafe constructs that can
introduce memory safety issues when the use of the return value had a
different shape resulting in false negatives for cases like:
return returnsUnsafe()
or
usesUnsafe(returnsUnsafe())
This PR changes the analysis to always take return types of function
calls into account.
rdar://157237301
This is a wild guess at what might be causing our persistent, random
String failures on the main branch:
```
Swift(macosx-x86_64) :: Prototypes/CollectionTransformers.swift
Swift(macosx-x86_64) :: stdlib/NSSlowString.swift
Swift(macosx-x86_64) :: stdlib/NSStringAPI.swift
Swift(macosx-x86_64) :: stdlib/StringIndex.swift
Swift-validation(macosx-x86_64) :: stdlib/String.swift
Swift-validation(macosx-x86_64) :: stdlib/StringBreadcrumbs.swift
Swift-validation(macosx-x86_64) :: stdlib/StringUTF8.swift
```
FWIW, it appears this is *not* caused by https://github.com/apple/swift/pull/62717:
that change has also landed on release/5.8, and I haven’t seen these
issues on that branch.
Our atomic breadcrumbs initialization vs its non-atomic loading
gives me an uneasy feeling that this may in fact be a long standing
synchronization issue that is only now causing problems (for whatever
reason). I am unable to reproduce these issues locally, so this guess
may be (and probably is) wildly off the mark, but this PR is likely
to be a good idea anyway, if only to rule out this possibility.
rdar://104751936
When the stdlib says not to check, it’s a good idea to actually not have any checking, so that we leave existing code paths unchanged. (And because we do trust that the stdlib is responsible about such things.)