With D101701, a function can no longer be nofree if it causes
caller-visible memory to be freed indirectly by another thread. The
checks introduced there are equivalent to the checks for nosync.
This change tightens those checks: only an atomic operation with release
(or higher) ordering can break the guarantee made by nofree. (Volatile
memory operations are still treated conservatively.)
A correctness argument is as follows. If a memory object is
dereferenceable at point A and freed at point B, then A must
happen-before B (otherwise, there is undefined behavior). If points A
and B are on different threads, then the only way that such a
happens-before relation can be introduced is if there is a release (or
stronger) ordering operation that "happens between" A and B on the
thread that executes A.